By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,098 Members | 1,950 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,098 IT Pros & Developers. It's quick & easy.

using "!!" in "c"

P: n/a
Hello,
I saw in some open source projects a use of "!!" in "C" code;
for example:
in some header file
#define event_pending(v) \
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

whereas evtchn_upcall_pending is of type unsigned char
(and also evtchn_upcall_mask is of type unsigned char).

What does "!!" operator do in this case ? Any ideas?
MR

Jan 18 '06 #1
Share this Question
Share on Google+
43 Replies


P: n/a
! is not operator.
so !! is read as not of not which implies true.

Jan 18 '06 #2

P: n/a
On 18 Jan 2006 01:28:23 -0800, ma******@gmail.com wrote:
Hello,
I saw in some open source projects a use of "!!" in "C" code;
for example:
in some header file
#define event_pending(v) \
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

whereas evtchn_upcall_pending is of type unsigned char
(and also evtchn_upcall_mask is of type unsigned char).

What does "!!" operator do in this case ? Any ideas?
MR

It is "not not", thta is, it checks its argument to see if it is not
zero.

Is is a way to make explicit that the argument is not a bool, and is
being tested for a non-zero value.

Zara
Jan 18 '06 #3

P: n/a
Zara wrote:
On 18 Jan 2006 01:28:23 -0800, ma******@gmail.com wrote:

I saw in some open source projects a use of "!!" in "C" code;
for example:
in some header file
#define event_pending(v) \
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

whereas evtchn_upcall_pending is of type unsigned char
(and also evtchn_upcall_mask is of type unsigned char).

What does "!!" operator do in this case ? Any ideas?


It is "not not", thta is, it checks its argument to see if it is not
zero.

Is is a way to make explicit that the argument is not a bool, and is
being tested for a non-zero value.


no, not really. In C a non-zero value is taken to be true. "!" as you
state is the not operator and yields either 0 (false) or 1 (true). So
"!!"
yeilds a "normalised" boolean value that is it has the same logical
value but is guaranteed to be 0 or 1. Using a truth table:-

x !x !!x
0 1 0
1 0 1
2 0 1

where "2" represents an arbitary non-zero value
--
Nick Keighley

Jan 18 '06 #4

P: n/a
oops! my previous post should have been addressed to Raguath not Zara.
It then would have read something like this:-
Nick Keighley wrote:
Raguath wrote:
On 18 Jan 2006 01:28:23 -0800, ma******@gmail.com wrote:
I saw in some open source projects a use of "!!" in "C" code;
for example:
in some header file
#define event_pending(v) \
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

whereas evtchn_upcall_pending is of type unsigned char
(and also evtchn_upcall_mask is of type unsigned char).

What does "!!" operator do in this case ? Any ideas?
! is not operator.
so !! is read as not of not which implies true.


oh, and leave some context in your posts

no, not really. In C a non-zero value is taken to be true. "!" as you
state is the not operator and yields either 0 (false) or 1 (true). So
"!!"
yeilds a "normalised" boolean value that is it has the same logical
value but is guaranteed to be 0 or 1. Using a truth table:-

x !x !!x
0 1 0
1 0 1
2 0 1

where "2" represents an arbitary non-zero value

--
Nick Keighley

Jan 18 '06 #5

P: n/a
ma******@gmail.com wrote:
What does "!!" operator do


!! is two instances of one operator.

(!(a)) means ((a) == 0)
(!!(a)) means ((a) != 0)

--
pete
Jan 18 '06 #6

P: n/a
ra*********@gmail.com wrote:
! is not operator.


You're wrong, it is an operator ;-)
August

--
I am the "ILOVEGNU" signature virus. Just copy me to your
signature. This email was infected under the terms of the GNU
General Public License.
Jan 18 '06 #7

P: n/a

<ma******@gmail.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
Hello,
I saw in some open source projects a use of "!!" in "C" code;
for example:
in some header file
#define event_pending(v) \
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

whereas evtchn_upcall_pending is of type unsigned char
(and also evtchn_upcall_mask is of type unsigned char).

What does "!!" operator do in this case ? Any ideas?
MR


!! is a good way of turning a scalar value into 1 or 0.

For example, this

printf("%p\n", (void *)"boo");

will output some value that's not 0, and very unlikely to be 1, e.g.,
0040300

However, this

printf("%p\n", (void *)!!"boo");

will output 000001, e.g., '1'

I've seen/used !! in functions that allocate memory, and return 1 if the
memory was allocated ok, else 0.

A routine like this would look something like ...

void * p;

int allocStuff(size_t n)
{
p = malloc(n);

return !!p;
}

int main(void)
{
if(allocStuff(...))
{
}
else
{
}
}

Although the code above would work if allocStuff simply returned the actual
pointer value, it would stop someone from finding out that fact, and doing
something like this ...

int main(void)
{
void * p1;

if(p1 = allocStuff(...))
{
// Aha, we've now got a pointer to the memory allocated!!!
}
else
{
}
}

Yes, in the code above [first], you'd also get the same thing by accessing
p, but I hope you get the gist of this simple example, and see how it could
be extended?
Jan 18 '06 #8

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

August Karlstrom wrote:
ra*********@gmail.com wrote:
! is not operator.

You're wrong, it is an operator ;-)


IIUC, ragnauth.cr /meant/ to say

! is "not" operator.

as in
! is the operator for "logical not"
- --

Lew Pitcher, IT Specialist, Enterprise Data Systems
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFDznCpagVFX4UWr64RAkxUAJ4nCK7v7Oj0faWIPdx22S 3B1xTkqgCg8LDh
v4QqWYNHcdtp7g6yosbiZNo=
=x7SK
-----END PGP SIGNATURE-----
Jan 18 '06 #9

P: n/a
Nick Keighley wrote:
Zara wrote:
On 18 Jan 2006 01:28:23 -0800, ma******@gmail.com wrote:

I saw in some open source projects a use of "!!" in "C" code;
for example:
in some header file
#define event_pending(v) \
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

whereas evtchn_upcall_pending is of type unsigned char
(and also evtchn_upcall_mask is of type unsigned char).

What does "!!" operator do in this case ? Any ideas?

It is "not not", thta is, it checks its argument to see if it is not
zero.

Is is a way to make explicit that the argument is not a bool, and is
being tested for a non-zero value.


no, not really. In C a non-zero value is taken to be true. "!" as you
state is the not operator and yields either 0 (false) or 1 (true). So
"!!"
yeilds a "normalised" boolean value that is it has the same logical
value but is guaranteed to be 0 or 1. Using a truth table:-

x !x !!x
0 1 0
1 0 1
2 0 1

where "2" represents an arbitary non-zero value


You make reference to it but your table doesn't reflect that C simply
defines logical true as non zero so you can't say that it's == 1 or 2 or
anything - only that it's non-zero.

More precisely:
x !x !!x
0 1 0 ie: logical false
1 0 != 0 ie: logical true
2 0 != 0 logical true

- Craig Taylor
http://www.ctalkobt.net

Jan 18 '06 #10

P: n/a
Lew Pitcher <Le*********@td.com> writes:
August Karlstrom wrote:
ra*********@gmail.com wrote:
! is not operator.


You're wrong, it is an operator ;-)


IIUC, ragnauth.cr /meant/ to say

! is "not" operator.

as in
! is the operator for "logical not"


Right, which is why Lew used the ";-)" operator.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 18 '06 #11

P: n/a
"pemo" <us***********@gmail.com> writes:
[snip]
!! is a good way of turning a scalar value into 1 or 0.
So is (value, 0) (i.e., a comma operator). It turns a scalar value
into 1 or 0. It just happens to be 0.

!! maps 0 to 0, and any non-zero value to 1, for any scalar operand.
For example, this

printf("%p\n", (void *)"boo");

will output some value that's not 0, and very unlikely to be 1, e.g.,
0040300
It will output some implementation-specific sequence of printing
characters. The sequence may or may not look like a number.
However, this

printf("%p\n", (void *)!!"boo");

will output 000001, e.g., '1'
That invokes undefined behavior.

"boo" yields a char* value. The "!" operator yields 1 if its operand
compares equal to 0, 0 otherwise. In this case, it compares the char*
value to a null pointer value. Since "boo" cannot be a null pointer,
!"boo" is guaranteed to yield 0. Applying "!" again yields the int
value 1.

So the above is equivalent to

printf("%p\n", (void*)1);

The conversion of the int value 1 to void* may yield a trap
representation; passing this to printf() (or doing anything else with
it) invokes undefined behavior.
I've seen/used !! in functions that allocate memory, and return 1 if the
memory was allocated ok, else 0.

A routine like this would look something like ...

void * p;

int allocStuff(size_t n)
{
p = malloc(n);

return !!p;
}


That's fine, since !!p is an int value and the function returns an int.

The thing to remember is that !!foo doesn't just normalize foo to 0 or
1; it yields a value of type int, regardless of the type of foo.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 18 '06 #12

P: n/a

<ma******@gmail.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
Hello,
I saw in some open source projects a use of "!!" in "C" code;
for example:
in some header file
#define event_pending(v) \
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

whereas evtchn_upcall_pending is of type unsigned char
(and also evtchn_upcall_mask is of type unsigned char).

What does "!!" operator do in this case ? Any ideas?


There is no "!!" operator. What you are seeing is
two adjacent "!" (logical 'not') operators. In a
Boolean context, any zero value is considered 'false',
any nonzero value, 'true'. C's explicit values for
reporting (e.g. with 'if()') 'true' and 'false' are
zero (0) and one (1) respectively.
0 == 0
!0 == 1
!!0 == 0

1 == 1
!1 == 0
!!1 == 1

42 == 42
!42 == 0
!!42 == 1
!! is sometimes used to convert a true (but not == 1)
value to 1.

-Mike
Jan 18 '06 #13

P: n/a
Craig Taylor <ct******@gmail.com> writes:
Nick Keighley wrote:

[...]
no, not really. In C a non-zero value is taken to be true. "!" as you
state is the not operator and yields either 0 (false) or 1 (true). So
"!!"
yeilds a "normalised" boolean value that is it has the same logical
value but is guaranteed to be 0 or 1. Using a truth table:-
x !x !!x
0 1 0
1 0 1
2 0 1
where "2" represents an arbitary non-zero value


You make reference to it but your table doesn't reflect that C simply
defines logical true as non zero so you can't say that it's == 1 or 2
or anything - only that it's non-zero.

More precisely:
x !x !!x
0 1 0 ie: logical false
1 0 != 0 ie: logical true
2 0 != 0 logical true


No, Craig's table is correct and is more precise than yours. The "!"
operator yields a value of type int; that value is guaranteed to be
either 0 or 1.

All C operators that yield logical values:
&& || ! == != < <= > >=
always yield a value of either 0 or 1. If any of them yield a
non-zero value other than 1, your compiler is buggy.

It's probably bad style to rely on this unless you have a specific
reason to do so.

All contexts that require a condition:
if()
while()
for(...;condition;...)
do while()
condition ? ... : ...
condition && condition
condition || condition
! condition
treat zero as false, and any non-zero value as true.

A *function* that returns a logical value (as type int) can reasonably
return any non-zero value for true; for example, the is*() functions
in <ctype.h> are allowed to do this.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 18 '06 #14

P: n/a
Keith Thompson wrote:
Lew Pitcher <Le*********@td.com> writes:
August Karlstrom wrote:
ra*********@gmail.com wrote:

! is not operator.
You're wrong, it is an operator ;-)

IIUC, ragnauth.cr /meant/ to say

! is "not" operator.

as in
! is the operator for "logical not"


Right, which is why Lew used the ";-)" operator.


;-) is an operator? I've never seen it before. Is this a C99 extension?

Does it modify the line of code that it's on to perform what you meant
it to do instead of how you coded it for? If so, I've been looking for
that for a while. (This may also explain why there's few C99 compilers
around... ). ;-)

- Craig Taylor
http://www.ctalkobt.net
Jan 18 '06 #15

P: n/a
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
Craig Taylor <ct******@gmail.com> writes:
Nick Keighley wrote:

[...]
no, not really. In C a non-zero value is taken to be true. "!" as you
state is the not operator and yields either 0 (false) or 1 (true). So
"!!"
yeilds a "normalised" boolean value that is it has the same logical
value but is guaranteed to be 0 or 1. Using a truth table:-
x !x !!x
0 1 0
1 0 1
2 0 1
where "2" represents an arbitary non-zero value


You make reference to it but your table doesn't reflect that C simply
defines logical true as non zero so you can't say that it's == 1 or 2
or anything - only that it's non-zero.

More precisely:
x !x !!x
0 1 0 ie: logical false
1 0 != 0 ie: logical true
2 0 != 0 logical true


No, Craig's table is correct and is more precise than yours.


Newsreader problem Keith?
Would have let it slide, but this is the 2nd post of yours I've
read in the last minute which improperly attributes quoted text.
Nick's table is the one you are claiming is more precise...
Craig's table is the one you are complaining about.

(note: the other attribution was further up thread...
August was the one who used the ";-)" operator, not Lew)
Jan 18 '06 #16

P: n/a
"Mark B" <so***@localbar.com> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
Craig Taylor <ct******@gmail.com> writes:
Nick Keighley wrote: [...]
no, not really. In C a non-zero value is taken to be true. "!" as you
state is the not operator and yields either 0 (false) or 1 (true). So
"!!"
yeilds a "normalised" boolean value that is it has the same logical
value but is guaranteed to be 0 or 1. Using a truth table:-
x !x !!x
0 1 0
1 0 1
2 0 1
where "2" represents an arbitary non-zero value

You make reference to it but your table doesn't reflect that C simply
defines logical true as non zero so you can't say that it's == 1 or 2
or anything - only that it's non-zero.

More precisely:
x !x !!x
0 1 0 ie: logical false
1 0 != 0 ie: logical true
2 0 != 0 logical true


No, Craig's table is correct and is more precise than yours.


Newsreader problem Keith?


Yes. Not the software, just the guy at the keyboard reading the news.
Would have let it slide, but this is the 2nd post of yours I've
read in the last minute which improperly attributes quoted text.
Nick's table is the one you are claiming is more precise...
Craig's table is the one you are complaining about.

(note: the other attribution was further up thread...
August was the one who used the ";-)" operator, not Lew)


My apologies, and thanks for catching my errors.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 18 '06 #17

P: n/a
In article <wl*************@bignews5.bellsouth.net>
Craig Taylor <ct******@gmail.com> wrote:
You make reference to it but your table doesn't reflect that C simply
defines logical true as non zero so you can't say that it's == 1 or 2 or
anything - only that it's non-zero.

More precisely:
x !x !!x
0 1 0 ie: logical false
1 0 != 0 ie: logical true
2 0 != 0 logical true


C distinguishes clearly between "input" and "output" logical values
for its logical operators (!, ||, &&): on input, any nonzero value is
true and zero is false, but on output, true is exactly 1.

Note that not all "apparently logical" functions are necessarily
logical functions, e.g., isspace() and so on from <ctype.h> do not
necessarily produce only 0-or-1.

See also <http://www.c-faq.com/bool/bool2.html>.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jan 18 '06 #18

P: n/a
Craig Taylor wrote:
Keith Thompson wrote:
Lew Pitcher <Le*********@td.com> writes:
August Karlstrom wrote:

ra*********@gmail.com wrote:

> ! is not operator.

You're wrong, it is an operator ;-)

IIUC, ragnauth.cr /meant/ to say

! is "not" operator.

as in
! is the operator for "logical not"

Right, which is why Lew used the ";-)" operator.


;-) is an operator? I've never seen it before. Is this a C99 extension?

Does it modify the line of code that it's on to perform what you meant
it to do instead of how you coded it for? If so, I've been looking for
that for a while. (This may also explain why there's few C99 compilers
around... ). ;-)


So you haven't heard about it? It's called the ironic statement
terminator. It's mostly used by expert C programmers writing programs
intended to be read by other experts. For instance

x = 5;-)

adds some interesting uncertainty to the statement `x = 5;'. These
people find the preciseness of the latter statement boring. The only way
to be sure of what an ironic statement really means is to get to know
the author really well.
August

--
I am the "ILOVEGNU" signature virus. Just copy me to your
signature. This email was infected under the terms of the GNU
General Public License.
Jan 18 '06 #19

P: n/a
August Karlstrom <fu********@comhem.se> writes:
Craig Taylor wrote:
Keith Thompson wrote:
Lew Pitcher <Le*********@td.com> writes:

August Karlstrom wrote:

> ra*********@gmail.com wrote:
>
>> ! is not operator.
>
> You're wrong, it is an operator ;-)

IIUC, ragnauth.cr /meant/ to say

! is "not" operator.

as in
! is the operator for "logical not"
Right, which is why Lew used the ";-)" operator.

August, not Lew. Sorry.
;-) is an operator? I've never seen it before. Is this a C99
extension?
Does it modify the line of code that it's on to perform what you
meant it to do instead of how you coded it for? If so, I've been
looking for that for a while. (This may also explain why there's few
C99 compilers around... ). ;-)


So you haven't heard about it? It's called the ironic statement
terminator. It's mostly used by expert C programmers writing programs
intended to be read by other experts. For instance

x = 5;-)

adds some interesting uncertainty to the statement `x = 5;'. These
people find the preciseness of the latter statement boring. The only
way to be sure of what an ironic statement really means is to get to
know the author really well.


Just as "!!" is effectively a double-negative operator, yielding the
same logical result as a single-positive operator, ";-)" is a
double-positive operator (pronounced "Yeah, right!"), yielding a
positively ambiguous result. The behavior is not merely undefined;
it's both ill-defined and ill-mannered.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 18 '06 #20

P: n/a
pemo wrote:
<ma******@gmail.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
Hello,
I saw in some open source projects a use of "!!" in "C" code;
for example:
in some header file
#define event_pending(v) \
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

whereas evtchn_upcall_pending is of type unsigned char
(and also evtchn_upcall_mask is of type unsigned char).

What does "!!" operator do in this case ? Any ideas?
!! is a good way of turning a scalar value into 1 or 0.


Yes.
For example, this

printf("%p\n", (void *)"boo");

will output some value that's not 0, and very unlikely to be 1, e.g.,
0040300
Fine.
However, this

printf("%p\n", (void *)!!"boo");

will output 000001, e.g., '1'


Or almost anything else since the conversion from integer to pointer is
implementation defined. If you want something like that do:
printf("%d\n", !!"boo");

<snip>
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Jan 18 '06 #21

P: n/a
Keith Thompson wrote:
August Karlstrom <fu********@comhem.se> writes:

.... snip ...

So you haven't heard about it? It's called the ironic
statement terminator. It's mostly used by expert C programmers
writing programs intended to be read by other experts. For
instance

x = 5;-)

adds some interesting uncertainty to the statement `x = 5;'.
These people find the preciseness of the latter statement
boring. The only way to be sure of what an ironic statement
really means is to get to know the author really well.


Just as "!!" is effectively a double-negative operator, yielding
the same logical result as a single-positive operator, ";-)" is
a double-positive operator (pronounced "Yeah, right!"), yielding
a positively ambiguous result. The behavior is not merely
undefined; it's both ill-defined and ill-mannered.


You are confusing things. There are the ambiguity operators :-)
and ;-), and the disgust operators ;-( and :-(, just to name a few
classifications. Disgust normally takes precedence.

Don't forget the inverses: (-: (-; )-: )-;
or the equivalents for squares: :-] ;-] :-[ ;-[

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 18 '06 #22

P: n/a
Chris Torek wrote:
.... snip ...
C distinguishes clearly between "input" and "output" logical
values for its logical operators (!, ||, &&): on input, any
nonzero value is true and zero is false, but on output, true is
exactly 1.

Note that not all "apparently logical" functions are necessarily
logical functions, e.g., isspace() and so on from <ctype.h> do
not necessarily produce only 0-or-1.

See also <http://www.c-faq.com/bool/bool2.html>.


Nor does strcmp(), another trap. The elusiveness and low
visibility of ! is a reason, to me, to #include <iso646.h> and use
the word "not".

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 18 '06 #23

P: n/a
ma******@gmail.com a écrit :
What does "!!" operator do <... ?


It's a combination of 2 unary not-operator. The type returned by the
not-operator is int and the value is 0 or 1.

It acts like the 'binary-converter-operator'. It converts 0 to a 0 and
non-0 to 1.

#include <stdio.h>

int main (void)
{
printf("%d\n", !!0); /* 0 */
printf("%d\n", !!123); /* 1 */

return 0;
}

--
A+

Emmanuel Delahaye
Jan 18 '06 #24

P: n/a
Lew Pitcher a écrit :
! is not operator.


You're wrong, it is an operator ;-)


IIUC, ragnauth.cr /meant/ to say

! is "not" operator.

as in
! is the operator for "logical not"


Yes, even I, had understood ! Noticed the smiley ?

--
A+

Emmanuel Delahaye
Jan 18 '06 #25

P: n/a
"Chuck F. " <cb********@yahoo.com> writes:
Chris Torek wrote:

... snip ...

C distinguishes clearly between "input" and "output" logical
values for its logical operators (!, ||, &&): on input, any
nonzero value is true and zero is false, but on output, true is
exactly 1.

Note that not all "apparently logical" functions are necessarily
logical functions, e.g., isspace() and so on from <ctype.h> do
not necessarily produce only 0-or-1.

See also <http://www.c-faq.com/bool/bool2.html>.


Nor does strcmp(), another trap. The elusiveness and low
visibility of ! is a reason, to me, to #include <iso646.h> and use
the word "not".


I don't find strcmp() to be much of a trap because I don't think of
its results as boolean. I know a lot of programmers write a string
equality operation as (!strcmp(s1, s2)); I prefer the more explicit
(strcmp(s1, s2) == 0).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 18 '06 #26

P: n/a
Chuck F. a écrit :
You are confusing things. There are the ambiguity operators :-) and
;-), and the disgust operators ;-( and :-(, just to name a few
classifications. Disgust normally takes precedence.

Don't forget the inverses: (-: (-; )-: )-;
or the equivalents for squares: :-] ;-] :-[ ;-[


Thanks for having tested ThunderBird's smiley interpretor.

These ones are not interpreted:

;-( (-: (-; )-: )-; :-] ;-] ;-[
--
A+

Emmanuel Delahaye
Jan 18 '06 #27

P: n/a
Keith Thompson wrote:
I don't find strcmp() to be much of a trap because I don't think of
its results as boolean.
strcmp is more similar to a compar function,
than it is to a boolean.
I know a lot of programmers write a string
equality operation as (!strcmp(s1, s2)); I prefer the more explicit
(strcmp(s1, s2) == 0).


So would I.

For pseudoboolean expressions like isspace(c),
I prefer to write
if (isspace(c))
or
if (!isspace(c))

For most other conditional expressions,
I prefer to compare explicitly to zero.

--
pete
Jan 18 '06 #28

P: n/a
Keith Thompson said:
Just as "!!" is effectively a double-negative operator, yielding the
same logical result as a single-positive operator,


....but ! necessarily the same numerical result.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jan 19 '06 #29

P: n/a

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"pemo" <us***********@gmail.com> writes:
[snip]
!! is a good way of turning a scalar value into 1 or 0.
So is (value, 0) (i.e., a comma operator). It turns a scalar value
into 1 or 0. It just happens to be 0.


What's the point here?
!! maps 0 to 0, and any non-zero value to 1, for any scalar operand.
For example, this

printf("%p\n", (void *)"boo");

will output some value that's not 0, and very unlikely to be 1, e.g.,
0040300

It will output some implementation-specific sequence of printing
characters. The sequence may or may not look like a number.


Can you explain this comment too? Is it an allusion to some obscure
minutiae in the std, like "In reality, an implementation is free to encode
an address such that it is displayed in egyptian hieroglyphics"?
However, this

printf("%p\n", (void *)!!"boo");

will output 000001, e.g., '1'


That invokes undefined behavior.

"boo" yields a char* value. The "!" operator yields 1 if its operand
compares equal to 0, 0 otherwise. In this case, it compares the char*
value to a null pointer value. Since "boo" cannot be a null pointer,
!"boo" is guaranteed to yield 0. Applying "!" again yields the int
value 1.

So the above is equivalent to

printf("%p\n", (void*)1);

The conversion of the int value 1 to void* may yield a trap
representation; passing this to printf() (or doing anything else with
it) invokes undefined behavior.

Interesting, so something like this is basically illegal/non-portable now?

void (* n)(void) = (void(*)(void))42;

n();

Years ago I used to use something like the above for invoking interrupt
routines.
Jan 19 '06 #30

P: n/a
On 2006-01-19, pemo <us***********@gmail.com> wrote:
That invokes undefined behavior.

"boo" yields a char* value. The "!" operator yields 1 if its operand
compares equal to 0, 0 otherwise. In this case, it compares the char*
value to a null pointer value. Since "boo" cannot be a null pointer,
!"boo" is guaranteed to yield 0. Applying "!" again yields the int
value 1.

So the above is equivalent to

printf("%p\n", (void*)1);

The conversion of the int value 1 to void* may yield a trap
representation; passing this to printf() (or doing anything else with
it) invokes undefined behavior.

Interesting, so something like this is basically illegal/non-portable now?

void (* n)(void) = (void(*)(void))42;

n();

Years ago I used to use something like the above for invoking interrupt
routines.


He's getting a bit ahead of himself - it is not undefined, it's
implementation-defined. But it's _always_ been non-portable - what's an
interrupt routine?
Jan 19 '06 #31

P: n/a

"Jordan Abel" <ra*******@gmail.com> wrote in message
news:sl***********************@random.yi.org...
On 2006-01-19, pemo <us***********@gmail.com> wrote:
That invokes undefined behavior.

"boo" yields a char* value. The "!" operator yields 1 if its operand
compares equal to 0, 0 otherwise. In this case, it compares the char*
value to a null pointer value. Since "boo" cannot be a null pointer,
!"boo" is guaranteed to yield 0. Applying "!" again yields the int
value 1.

So the above is equivalent to

printf("%p\n", (void*)1);

The conversion of the int value 1 to void* may yield a trap
representation; passing this to printf() (or doing anything else with
it) invokes undefined behavior.

Interesting, so something like this is basically illegal/non-portable
now?

void (* n)(void) = (void(*)(void))42;

n();

Years ago I used to use something like the above for invoking interrupt
routines.


He's getting a bit ahead of himself - it is not undefined, it's
implementation-defined. But it's _always_ been non-portable - what's an
interrupt routine?


Interrupt routine. A routine (usually held in ROM) that is normally
[caused] to be invoked by some hardware 'event' [or 'interrupt'] - e.g.,
when the hardware clocks ticks, a hardware interrupt is triggered so that
the OS etc can keep track of the current time, and the fact that the time
has just changed, i.e., this saves the OS from polling here. The location
of the routine[s] that need calling when these events occur were held in a
table at a fixed location. So, if you were writing some lowish level code
that might want to interact with, say, the harddrive controller, it was
often nice to do at least some part of this via the harddrive's documented
interrupt interface.

So, you'd often have to fetch an interrupt routine's address, and then call
it ...

typically, it looked something like this:

typedef Interrupts int; // Used as a function pointer 'value' for any
interrupt routine.

Interrupts * inttab;

// Base address of int table. inttab[index] yields index interrupt vector.
The actual addresses are already there - BIOS!
//
inttab = (Interrupts *)0; // 0 = base address on int table. inttab[x]
yields address of x's interrupt vector's service routine.

....

// Trigger int 10

void(*n)();

// Get int 10's service routine address.

n = (void)(*)())inttab[10];

// Invoke int 10.

n();



Jan 19 '06 #32

P: n/a
pemo wrote:
"Jordan Abel" <ra*******@gmail.com> wrote in message
news:sl***********************@random.yi.org...
On 2006-01-19, pemo <us***********@gmail.com> wrote:
That invokes undefined behavior.

"boo" yields a char* value. The "!" operator yields 1 if its operand
compares equal to 0, 0 otherwise. In this case, it compares the char*
value to a null pointer value. Since "boo" cannot be a null pointer,
!"boo" is guaranteed to yield 0. Applying "!" again yields the int
value 1.

So the above is equivalent to

printf("%p\n", (void*)1);

The conversion of the int value 1 to void* may yield a trap
representation; passing this to printf() (or doing anything else with
it) invokes undefined behavior.

Interesting, so something like this is basically illegal/non-portable
now?

void (* n)(void) = (void(*)(void))42;

n();

Years ago I used to use something like the above for invoking interrupt
routines. He's getting a bit ahead of himself - it is not undefined, it's
implementation-defined. But it's _always_ been non-portable - what's an
interrupt routine?


Interrupt routine. A routine (usually held in ROM) that is normally


I'm sure Jordan, Keith and most of the other regulars know what an ISR
is. It does not change the fact that what you are suggesting is
non-portable.

Lets take the issue of where the interrupt vector table is. I've used
systems with it at the bottom of memory next to the reset vector and
therefore in ROM, I've used systems with it at the bottom of memory with
the reset vector at the tom, so the interrupt vector table was in RAM,
I've used systems where the location of the interrupt vector table is
configurable, so it could be anywhere! That show your hard coded address
is non-portable.

I've also used sytems where the interupt vector table does *not* contain
some kind of jump/call instruction, so you would actually need another
level of indirection on those systems.

<snip>
table at a fixed location. So, if you were writing some lowish level code
that might want to interact with, say, the harddrive controller, it was
often nice to do at least some part of this via the harddrive's documented
interrupt interface.
Not something I've needed to do, but i'll accept it's been useful to
you. However, useful does not mean portable. So now lets deal with the
issue of calling an ISR. I've used systems where the return call/return
mechanism for an ISR was not the same as the mechanism for a normal
function. So to call an ISR you would actually have to use a CALLI
instruction, when the compiler would also emit a CALL instruction. So,
even having used some magic to get the address of the ISR you *still*
can't call it from C on a system like this and if you try you will crash
your program even if the ISR does nothing other than return.
So, you'd often have to fetch an interrupt routine's address, and then call
it ...


<snip non-portable code>

Which you can't do portably. This is not to say you can't do it at all,
on some systems you can.

The conversion from integer to pointer is implementation defined (apart
from an integer *constant* of 0) and could generate a trap
representation. If it generates a trap representation then evaluating it
(which you have to do to assign it to a pointer unless you cheat and
do it via an unsigned char pointer) invokes undefined behaviour. Even if
you manage to get past that, you still leave standard C a long way
behind when you try calling it.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Jan 19 '06 #33

P: n/a
pemo wrote:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"pemo" <us***********@gmail.com> writes:
[snip]
!! is a good way of turning a scalar value into 1 or 0. So is (value, 0) (i.e., a comma operator). It turns a scalar value
into 1 or 0. It just happens to be 0.


What's the point here?


I believe that Keith was just pointing out that your specification of
what !! does was incomplete. What he wrote met your specification but
would generally be pointless in real code (there are potentially some
exceptions) and does not do what !! does.
!! maps 0 to 0, and any non-zero value to 1, for any scalar operand.
For example, this

printf("%p\n", (void *)"boo");

will output some value that's not 0, and very unlikely to be 1, e.g.,
0040300
It will output some implementation-specific sequence of printing
characters. The sequence may or may not look like a number.


Can you explain this comment too? Is it an allusion to some obscure
minutiae in the std, like "In reality, an implementation is free to encode
an address such that it is displayed in egyptian hieroglyphics"?


One very common format of output is something like "1234:5678", another
is something like "0x12345678". You will note that the first does not
look like a number because of the colon. Another common output is
something like "(null)" which looks even less like a number. What %p
prints can be in any format as long as it can be read by a %p in a scanf
on that implementation and yield the original pointer. Frequently
(though it is not required) it is whatever format is generally used in
printed material for addresses, and when an address on a machine is not
a simple thing (e.g. segment and offset as supported by x86 processors)
that is quite likely to mean the output won't look like a simple
integer. Egyptian hieroglyphics could legally be used as long they were
part of the execution character set and scanf processed them appropriately.
However, this

printf("%p\n", (void *)!!"boo");

will output 000001, e.g., '1'

That invokes undefined behavior.

"boo" yields a char* value. The "!" operator yields 1 if its operand
compares equal to 0, 0 otherwise. In this case, it compares the char*
value to a null pointer value. Since "boo" cannot be a null pointer,
!"boo" is guaranteed to yield 0. Applying "!" again yields the int
value 1.

So the above is equivalent to

printf("%p\n", (void*)1);

The conversion of the int value 1 to void* may yield a trap
representation; passing this to printf() (or doing anything else with
it) invokes undefined behavior.


Well, it only conditionally invokes undefined behaviour. If it happens
not to produce a trap representation then it is only implementation
defined behaviour IIRC. Of course, it should still generally be treated
as undefined behaviour.
Interesting, so something like this is basically illegal/non-portable now?

void (* n)(void) = (void(*)(void))42;

n();

Years ago I used to use something like the above for invoking interrupt
routines.


What you show the above has *always* been non-portable.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Jan 19 '06 #34

P: n/a
<snip>
So is (value, 0) (i.e., a comma operator). It turns a scalar value
into 1 or 0. It just happens to be 0.
What's the point here?

I believe that Keith was just pointing out that your specification of what !! does was incomplete. What he wrote met your specification but
would generally be pointless in real code (there are potentially some
exceptions) and does not do what !! does.
If that *IS* the case, it seems um, rather unnecessarily pedantic - I
believe that what I said was clear enough - and corrrect in as far as it
went: and I also didn't say it was the only way to do something .... so why
point out alternatives? Maybe it's necessary to produce litanies containing
alternative possibilities for each non-exhaustive statement ever made here
sometimes?

printf("%p\n", (void *)"boo");

will output some value that's not 0, and very unlikely to be 1, e.g.,
0040300
It will output some implementation-specific sequence of printing
characters. The sequence may or may not look like a number.


Can you explain this comment too? Is it an allusion to some obscure
minutiae in the std, like "In reality, an implementation is free to encode
an address such that it is displayed in egyptian hieroglyphics"?

One very common format of output is something like "1234:5678", another is something like "0x12345678". <snip>
Ah, so it was as I expected - an allusion to some obscure minutiae [well, it
is isn't it - letter-of-the-law-correct-or-not] that seems picky and
generally non-constructive. The two examples you gave look like numbers to
me. And I would hazard a guess that most every compiler outputs something
similar - even if it doesn't *have to*. So, saying that a compiler *could*
output this in a braille encoding of the morse-code interpretation of
egyptian hieroglyphics is kinda like saying that there is a remote
possibility that you *could* pick up a book which is written in English -
but that you can't read - because the author decided to choose a remote
vocabulary and to 'encode' his/her prose in such an impenetrable way as it
make it more or less impossible. Both situations *could* exist, but both
are, in reality, unlikely to - so what's the point in making a noise about
it?

Interesting, so something like this is basically illegal/non-portable
now?

void (* n)(void) = (void(*)(void))42;

n();

Years ago I used to use something like the above for invoking interrupt
routines.


What you show the above has *always* been non-portable.

Yes [I know!], my V.POOR wording - the question ought to have been ... is
the code illegal, without going through the unsigned char * route?

Jan 19 '06 #35

P: n/a
pemo wrote:

Please quote properly and leave in the attribution lines. If OE gives
you problems you can try searching for and using QuoteFix. You were
quoting properly previously and this time I'm going to fix it.
Flash Gordon wrote:
pemo wrote:
<snip>
So is (value, 0) (i.e., a comma operator). It turns a scalar value
into 1 or 0. It just happens to be 0.
What's the point here?
I believe that Keith was just pointing out that your specification of

what !! does was incomplete. What he wrote met your specification but
would generally be pointless in real code (there are potentially some
exceptions) and does not do what !! does.


If that *IS* the case, it seems um, rather unnecessarily pedantic -


This is CLC, people *are* pedantic here!
I
believe that what I said was clear enough - and corrrect in as far as it
went: and I also didn't say it was the only way to do something .... so why
point out alternatives? Maybe it's necessary to produce litanies containing
alternative possibilities for each non-exhaustive statement ever made here
sometimes?
Pointing out holes in what people say is not uncommon here.
> printf("%p\n", (void *)"boo");
>
> will output some value that's not 0, and very unlikely to be 1, e.g.,
> 0040300
It will output some implementation-specific sequence of printing
characters. The sequence may or may not look like a number.
Can you explain this comment too? Is it an allusion to some obscure
minutiae in the std, like "In reality, an implementation is free to encode
an address such that it is displayed in egyptian hieroglyphics"?
One very common format of output is something like "1234:5678", another
is something like "0x12345678". <snip>


Ah, so it was as I expected - an allusion to some obscure minutiae [well, it


You think x86 based machines are obscure minutiae?
is isn't it - letter-of-the-law-correct-or-not] that seems picky and
generally non-constructive. The two examples you gave look like numbers to
me. And I would hazard a guess that most every compiler outputs something
Numbers do not have colons in the middle, at least not in any
representation I've come across and "(null)" is definitely *not* a
number which was another example I gave but you snipped.

<snip>
make it more or less impossible. Both situations *could* exist, but both
are, in reality, unlikely to - so what's the point in making a noise about
it?


Implementations which print out the address with a : in the middle are
very real, and the processor for which such implementations were written
are still in current use.
Interesting, so something like this is basically illegal/non-portable
now?

void (* n)(void) = (void(*)(void))42;

n();

Years ago I used to use something like the above for invoking interrupt
routines.

What you show the above has *always* been non-portable.


Yes [I know!], my V.POOR wording - the question ought to have been ... is
the code illegal, without going through the unsigned char * route?


Subject to me missing errors what you are suggesting is perfectly
acceptable syntactically and the compiler is not required to produce a
diagnostic. So in that sense it is "legal". However, since it invokes
undefined behaviour it is in another sense "illegal". So take your pick.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Jan 19 '06 #36

P: n/a
"pemo" <us***********@gmail.com> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"pemo" <us***********@gmail.com> writes:
[snip]
!! is a good way of turning a scalar value into 1 or 0.


So is (value, 0) (i.e., a comma operator). It turns a scalar value
into 1 or 0. It just happens to be 0.


What's the point here?
!! maps 0 to 0, and any non-zero value to 1, for any scalar operand.
For example, this

printf("%p\n", (void *)"boo");

will output some value that's not 0, and very unlikely to be 1, e.g.,
0040300

It will output some implementation-specific sequence of printing
characters. The sequence may or may not look like a number.


Can you explain this comment too? Is it an allusion to some obscure
minutiae in the std, like "In reality, an implementation is free to encode
an address such that it is displayed in egyptian hieroglyphics"?


I was going to post an explanation of what I meant, but Flash Gordon's
response explains it at least as well as I would have.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 19 '06 #37

P: n/a
"pemo" <us***********@gmail.com> writes:
<snip>
So is (value, 0) (i.e., a comma operator). It turns a scalar value
into 1 or 0. It just happens to be 0.


What's the point here?

I believe that Keith was just pointing out that your specification of

what !! does was incomplete. What he wrote met your specification but
would generally be pointless in real code (there are potentially some
exceptions) and does not do what !! does.
If that *IS* the case, it seems um, rather unnecessarily pedantic - I
believe that what I said was clear enough - and corrrect in as far as it
went: and I also didn't say it was the only way to do something .... so why
point out alternatives? Maybe it's necessary to produce litanies containing
alternative possibilities for each non-exhaustive statement ever made here
sometimes?


(A number of attributions were snipped. I wrote the text starting
with "So is (value, 0)", pemo wrote the text starting with "What's the
point here?", and Flash Gordon wrote the text starting with "I believe
that Keith was". Please leave attributions in place. Thanks.)

What you wrote was:

!! is a good way of turning a scalar value into 1 or 0.

That's not a useful specification unless you also specify *when*
it yields 0 and when it yields 1. By itself, it doesn't provide any
clue of why you'd want to turn a scalar value into 1 or 0. I was just
emphasizing the fact that !! maps 0 to 0 and all non-zero mappings
to 1. There are many many other possible mappings.

Whether I was being overly pedantic is a matter of opinion, of course.
I likely wouldn't have bothered mentioning it if I weren't commenting
on other things in your article.
printf("%p\n", (void *)"boo");

will output some value that's not 0, and very unlikely to be 1, e.g.,
0040300

It will output some implementation-specific sequence of printing
characters. The sequence may or may not look like a number.


Can you explain this comment too? Is it an allusion to some obscure
minutiae in the std, like "In reality, an implementation is free to encode
an address such that it is displayed in egyptian hieroglyphics"?

One very common format of output is something like "1234:5678", another

is something like "0x12345678". <snip>

Ah, so it was as I expected - an allusion to some obscure minutiae [well, it
is isn't it - letter-of-the-law-correct-or-not] that seems picky and
generally non-constructive. The two examples you gave look like numbers to
me. And I would hazard a guess that most every compiler outputs something
similar - even if it doesn't *have to*. So, saying that a compiler *could*
output this in a braille encoding of the morse-code interpretation of
egyptian hieroglyphics is kinda like saying that there is a remote
possibility that you *could* pick up a book which is written in English -
but that you can't read - because the author decided to choose a remote
vocabulary and to 'encode' his/her prose in such an impenetrable way as it
make it more or less impossible. Both situations *could* exist, but both
are, in reality, unlikely to - so what's the point in making a noise about
it?


No, this is not "some obscure minutiae", this is part of a basic
understanding of the language.

Here's what the standard says about the "%p" format for the *printf()
functions:

The argument shall be a pointer to void. The value of the pointer
is converted to a sequence of printing characters, in an
implementation-defined manner.

There's also some wording for the *scanf() functions saying that it
can read the same format produced by *printf().

There is no implication that the output looks anything like a number,
and portable code cannot depend on any particular output format. It
happens that most implementations use something that looks like a
numeric format, possibly with extra decorations (leading "0x",
inserted ':', etc.). One system I just tried prints a hexadecimal
string *without* a leading "0x", such as "ffbff374", which happens to
be a valid identifier.

It's tempting to think that addresses are just another kind of number,
but that's a dangerous conceptual trap. They're often implemented
that way, but a C address or pointer value should be thought of as an
opaque entity that can be used to access other entities.

In any case, the example you chose didn't illustrate the point you
were making very well.
Interesting, so something like this is basically illegal/non-portable
now?

void (* n)(void) = (void(*)(void))42;

n();

Years ago I used to use something like the above for invoking interrupt
routines.


That's legal but non-portable. The conversion of the int value 42 to
a pointer-to-function type yields an implementation-defined result; it
could be a trap representation. If there doesn't happen to be a
function of the proper type whose address is whatever you get by
converting the int value 42, Bad Things Will Happen.

Of course this is a perfectly legitimate thing to do as long as you
really know what's going on and you're aware that it's non-portable.

On some systems, converting an integer to a pointer-to-function might
*never* yield a meaningful value. (For example, I think the AS/400
has a very exotic format for function pointers.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 19 '06 #38

P: n/a

"Flash Gordon" <sp**@flash-gordon.me.uk> wrote in message
news:kr************@news.flash-gordon.me.uk...
pemo wrote:

Please quote properly and leave in the attribution lines. If OE gives you
problems you can try searching for and using QuoteFix. You were quoting
properly previously and this time I'm going to fix it.

Sorry, I'm a terrible poster, and I'll look at QuoteFix.

Flash Gordon wrote:
pemo wrote:
<snip>

> So is (value, 0) (i.e., a comma operator). It turns a scalar value
> into 1 or 0. It just happens to be 0.
What's the point here?

I believe that Keith was just pointing out that your specification of
what !! does was incomplete. What he wrote met your specification but
would generally be pointless in real code (there are potentially some
exceptions) and does not do what !! does.


If that *IS* the case, it seems um, rather unnecessarily pedantic -


This is CLC, people *are* pedantic here!
I
believe that what I said was clear enough - and corrrect in as far as it
went: and I also didn't say it was the only way to do something .... so
why point out alternatives? Maybe it's necessary to produce litanies
containing alternative possibilities for each non-exhaustive statement
ever made here sometimes?


Pointing out holes in what people say is not uncommon here.
>> printf("%p\n", (void *)"boo");
>>
>> will output some value that's not 0, and very unlikely to be 1, e.g.,
>> 0040300
> It will output some implementation-specific sequence of printing
> characters. The sequence may or may not look like a number.
Can you explain this comment too? Is it an allusion to some obscure
minutiae in the std, like "In reality, an implementation is free to
encode an address such that it is displayed in egyptian hieroglyphics"?

One very common format of output is something like "1234:5678", another
is something like "0x12345678". <snip>


Ah, so it was as I expected - an allusion to some obscure minutiae [well,
it


You think x86 based machines are obscure minutiae?

No, not that! [see also below], rather that the comment I thought
uneccesary, *was* (IMHO)

It was essentially 'pulling me up' for stating that the output *might* be
0040300 [or 0123456, or 123, or 34234234234234234] - and that I didn't add
some, 'oh, and it might just be in output in hieroglyphics on your
implementation'!

Maybe the point was made so that some 'knumb nuts' didn't get the wrong end
of the stick, or maybe it was made just to remind someone [who I don't know]
that the output might actually be different from the example - maybe it was
just made to personally annoy me - I dunno, but it pissed me off anyway!
is isn't it - letter-of-the-law-correct-or-not] that seems picky and
generally non-constructive. The two examples you gave look like numbers
to me. And I would hazard a guess that most every compiler outputs
something
Numbers do not have colons in the middle, at least not in any
representation I've come across and "(null)" is definitely *not* a number
which was another example I gave but you snipped.

Yes, my phd wasn't wasted - and I've noticed that numbers don't have numbers
in the middle **using standard notation [see below]** - but they *can* have
camels in the middle if *you* want them to - and if you want to use such
notation personally - as some legal characterisation of some abstract scalar
view of the world. Which comes back to a problem with this ... if the
output can be anything, well, we ought to always include standard
disclaimers about *any* claim we make here regarding *any* output.
Ridiculus - so, lets point it out when it's properly pertinent, and not just
when we just feel the urge to bump our gums, and add some white noise into
the system?
Numbers do not have colons in the middle


Actually, that's rubbish, as I used them for many years with segmented
architectures - such numbers then meant as much to me - as in they had an
intuitive meaning for me (as 123 does now/then). This last bit is a little
like the 'pulling up' I had

'Actually the output of pemo's mathematics will be a pemo
implementation-specific sequence of printing
characters [maybe]. The sequence may or may not look like any number you're
used to'

Irksome eh?


Jan 19 '06 #39

P: n/a
On 2006-01-19, Flash Gordon <sp**@flash-gordon.me.uk> wrote:
Subject to me missing errors what you are suggesting is perfectly
acceptable syntactically and the compiler is not required to produce a
diagnostic. So in that sense it is "legal". However, since it invokes
undefined behaviour it is in another sense "illegal". So take your pick.


It does not. The conversion is implementation-defined. While the program
still cannot be strictly conforming, there is no undefined behavior
involved.

If I do this on my system, I will get a segmentation fault. Furthermore,
it will happen when the pointer is dereferenced, not when it is
assigned. While there is no documentation that actually says this _as
such_, all parts of the chain of events from the int/pointer conversion
to the mapping of the virtual memory page containing address 42 to the
conditions under which the signal in question will be raised are
documented _somewhere_, and it can be inferred from these facts without
ever attempting to enter, compile, or run the code.

I believe that the implementation is free to leave certain
implementation-defined aspects undefined, such as if the address
0x80484f8 were instead used. This happens to, in my test program, be the
address where the symbol 'main' is mapped. Since the address is in a
text page, i can attempt to call it and arbitrary code may be run, in
this case, a recursive call to main(). However, none of this is defined
by my implementation. However, from the point of view of the C standard,
implementation-undefined behavior is still implementation-defined.
Jan 19 '06 #40

P: n/a

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"pemo" <us***********@gmail.com> writes:
<snip>
So is (value, 0) (i.e., a comma operator). It turns a scalar value
into 1 or 0. It just happens to be 0.

What's the point here?
I believe that Keith was just pointing out that your specification of

what !! does was incomplete. What he wrote met your specification but
would generally be pointless in real code (there are potentially some
exceptions) and does not do what !! does.
If that *IS* the case, it seems um, rather unnecessarily pedantic - I
believe that what I said was clear enough - and corrrect in as far as it
went: and I also didn't say it was the only way to do something .... so
why
point out alternatives? Maybe it's necessary to produce litanies
containing
alternative possibilities for each non-exhaustive statement ever made
here
sometimes?


(A number of attributions were snipped. I wrote the text starting
with "So is (value, 0)", pemo wrote the text starting with "What's the
point here?", and Flash Gordon wrote the text starting with "I believe
that Keith was". Please leave attributions in place. Thanks.)


After this reply, I'll try and remember to simply enter any further replies
I make to posts at the bottom of any existing text - and then let others
either ignore my posts, or else figure out to what it is I might be
referring - seems like I'll never get the hang of this process, and if I'm
black-flagged, knobbled, f**ked up the ass [or whatever the proper 'in the
know' usenet term is] by some for not posting correctly, at least I won't be
committing the ultimate sin: top posting.

What you wrote was:

!! is a good way of turning a scalar value into 1 or 0.

That's not a useful specification unless you also specify *when*
it yields 0 and when it yields 1. By itself, it doesn't provide any
clue of why you'd want to turn a scalar value into 1 or 0. I was just
emphasizing the fact that !! maps 0 to 0 and all non-zero mappings
to 1. There are many many other possible mappings.
By itself, it doesn't provide any clue of why you'd want to turn a scalar
value into 1 or 0.
'By itself' - yes - which is why I then gave an example (malloc).
Whether I was being overly pedantic is a matter of opinion, of course.
I likely wouldn't have bothered mentioning it if I weren't commenting
on other things in your article.
> printf("%p\n", (void *)"boo");
>
> will output some value that's not 0, and very unlikely to be 1, e.g.,
> 0040300

It will output some implementation-specific sequence of printing
characters. The sequence may or may not look like a number.

Can you explain this comment too? Is it an allusion to some obscure
minutiae in the std, like "In reality, an implementation is free to
encode
an address such that it is displayed in egyptian hieroglyphics"?

One very common format of output is something like "1234:5678", another

is something like "0x12345678". <snip>

Ah, so it was as I expected - an allusion to some obscure minutiae [well,
it
is isn't it - letter-of-the-law-correct-or-not] that seems picky and
generally non-constructive. The two examples you gave look like numbers
to
me. And I would hazard a guess that most every compiler outputs
something
similar - even if it doesn't *have to*. So, saying that a compiler
*could*
output this in a braille encoding of the morse-code interpretation of
egyptian hieroglyphics is kinda like saying that there is a remote
possibility that you *could* pick up a book which is written in English -
but that you can't read - because the author decided to choose a remote
vocabulary and to 'encode' his/her prose in such an impenetrable way as
it
make it more or less impossible. Both situations *could* exist, but both
are, in reality, unlikely to - so what's the point in making a noise
about
it?


No, this is not "some obscure minutiae", this is part of a basic
understanding of the language.

Here's what the standard says about the "%p" format for the *printf()
functions:

The argument shall be a pointer to void. The value of the pointer
is converted to a sequence of printing characters, in an
implementation-defined manner.

There's also some wording for the *scanf() functions saying that it
can read the same format produced by *printf().

There is no implication that the output looks anything like a number,
and portable code cannot depend on any particular output format.


Ok, so this is where the problem is - although the OP might not give a
flying f**k about it, as they also might possibly not give the same for
portability - you're saying that I should have added ...

"will output some value that's not 0, and very unlikely to be 1, e.g.,
0040300. But remember that nothing is said in the C stds about the actual
output here, so you might see output that's in a format that you might not
readily understand for example, some version of printf might output cockney
rhyming slang! - "two fat ladies, two rubber ducks, and a ton" (meaning
8822100 in base 10)"



Jan 19 '06 #41

P: n/a
"pemo" <us***********@gmail.com> writes:
"Flash Gordon" <sp**@flash-gordon.me.uk> wrote in message
news:kr************@news.flash-gordon.me.uk...

[...]
You think x86 based machines are obscure minutiae?


No, not that! [see also below], rather that the comment I thought
uneccesary, *was* (IMHO)

It was essentially 'pulling me up' for stating that the output *might* be
0040300 [or 0123456, or 123, or 34234234234234234] - and that I didn't add
some, 'oh, and it might just be in output in hieroglyphics on your
implementation'!

Maybe the point was made so that some 'knumb nuts' didn't get the wrong end
of the stick, or maybe it was made just to remind someone [who I don't know]
that the output might actually be different from the example - maybe it was
just made to personally annoy me - I dunno, but it pissed me off anyway!


I did not intend to be offensive. In fact, I don't believe that I
was, and I'm surprised that you took offense. Feel free to interpret
my comments as a helpful commentary on what you wrote rather than as a
correction. And grow a thicker skin.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 19 '06 #42

P: n/a
pemo wrote:
"Flash Gordon" <sp**@flash-gordon.me.uk> wrote in message
news:kr************@news.flash-gordon.me.uk...
pemo wrote:

Please quote properly and leave in the attribution lines. If OE gives you
problems you can try searching for and using QuoteFix. You were quoting
properly previously and this time I'm going to fix it.
Sorry, I'm a terrible poster, and I'll look at QuoteFix.


I would not class you as a terrible poster. The terrible posters are
those who make no effort or deliberately go against convention. You may
make mistakes, but you are attempting to do it correctly. That puts you
on the good side rather than the bad. To make it clear, I have reason to
suspect that OE sometimes does the wrong thing even when users have done
their best to configure it correctly, but I've heard from people I
respect that QuoteFix helps to make OE behave nicely.
Flash Gordon wrote:
pemo wrote:
<snip>
printf("%p\n", (void *)"boo");
>>>
>>> will output some value that's not 0, and very unlikely to be 1, e.g.,
>>> 0040300
>> It will output some implementation-specific sequence of printing
>> characters. The sequence may or may not look like a number.
> Can you explain this comment too? Is it an allusion to some obscure
> minutiae in the std, like "In reality, an implementation is free to
> encode an address such that it is displayed in egyptian hieroglyphics"?
One very common format of output is something like "1234:5678", another
is something like "0x12345678". <snip>
Ah, so it was as I expected - an allusion to some obscure minutiae [well,
it
You think x86 based machines are obscure minutiae?


No, not that! [see also below], rather that the comment I thought
uneccesary, *was* (IMHO)


That is not the way your comment that I was making "an allusion to some
obscure minutiae" reads to me. <shrug>
It was essentially 'pulling me up' for stating that the output *might* be
0040300 [or 0123456, or 123, or 34234234234234234] - and that I didn't add
some, 'oh, and it might just be in output in hieroglyphics on your
implementation'!
No, it was not you picking a number, but your wording read to me as
implying it would be a simple number.
Maybe the point was made so that some 'knumb nuts' didn't get the wrong end
of the stick, or maybe it was made just to remind someone [who I don't know]
that the output might actually be different from the example - maybe it was
just made to personally annoy me - I dunno, but it pissed me off anyway!
It wasn't made to annoy you, or to show you up, or anything like that.
is isn't it - letter-of-the-law-correct-or-not] that seems picky and
generally non-constructive. The two examples you gave look like numbers
to me. And I would hazard a guess that most every compiler outputs
something

Numbers do not have colons in the middle, at least not in any
representation I've come across and "(null)" is definitely *not* a number
which was another example I gave but you snipped.


Yes, my phd wasn't wasted - and I've noticed that numbers don't have numbers
in the middle **using standard notation [see below]** - but they *can* have
camels in the middle if *you* want them to - and if you want to use such
notation personally - as some legal characterisation of some abstract scalar
view of the world.


If you put a camel in the middle it won't look like a number to most
people, it will look like 2 numbers separated by a camel. Just as two
numbers seperated by a colon looks like two numbers separated by a colon
to most people.
Which comes back to a problem with this ... if the
output can be anything, well, we ought to always include standard
disclaimers about *any* claim we make here regarding *any* output.
Ridiculus - so, lets point it out when it's properly pertinent, and not just
when we just feel the urge to bump our gums, and add some white noise into
the system?
For most things the output cannot be anything, but letting people who
don't know any better think that pointers are basically the same as
numeric types is dangerous.
Numbers do not have colons in the middle


Actually, that's rubbish, as I used them for many years with segmented
architectures - such numbers then meant as much to me - as in they had an
intuitive meaning for me (as 123 does now/then). This last bit is a little
like the 'pulling up' I had


Show a "number" with a colon in the middle to a mathematician and they
won't think of it as a number. Explain to them that 0010:0000 is the
same as 0000:0010 because you multiply the number before the colon by 16
and add it to the other and they will probably consider it to be two
numbers separated by an operator. Most of the people I've talked to
about x86 systems would also consider it to be two numbers, a segment
and an offset, not as one number, and as an ex-assembly language
programmer there have been times when the distinction has been very
important.
'Actually the output of pemo's mathematics will be a pemo
implementation-specific sequence of printing
characters [maybe]. The sequence may or may not look like any number you're
used to'


Well, your explicit statement that the value would not be 0 is not
necessarily correct and so should not have been stated as fact, and I
know of systems where it is very easy to end up with a pointer to
address 1 (and possibly 0 as well, but I can't be certain of that since
I can't remember what was used for a null pointer) since it is normal
memory at that address. Had you not said what values it would not be I
might not have bothered commenting, but that combined with the rest of
what you were saying looked to me like it would read to the naive as if
pointers where just integers.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Jan 20 '06 #43

P: n/a
pemo wrote:
"Keith Thompson" <ks***@mib.org> wrote in message

.... snip ...

(A number of attributions were snipped. I wrote the text starting
with "So is (value, 0)", pemo wrote the text starting with "What's the
point here?", and Flash Gordon wrote the text starting with "I believe
that Keith was". Please leave attributions in place. Thanks.)


After this reply, I'll try and remember to simply enter any further
replies I make to posts at the bottom of any existing text - and
then let others either ignore my posts, or else figure out to what
it is I might be referring - seems like I'll never get the hang of
this process, and if I'm black-flagged, knobbled, f**ked up the ass
[or whatever the proper 'in the know' usenet term is] by some for
not posting correctly, at least I won't be committing the ultimate
sin: top posting.


The other sin is failing to snip. The count of '>' marks on the
left keeps track of the attributee (with a one-off error :-) You
should also try to keep your line width under 72 (I use 67).
Notice how I have removed attribution lines only for material
totally excised. See the following references.

http://www.netmeister.org/news/learn2quote.html
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.greenend.org.uk/rjk/2000/06/14/quoting.html
http://www.i-hate-computers.demon.co.uk/
http://web.ukonline.co.uk/g.mccaugha...ks/uquote.html
http://www.cs.indiana.edu/docproject/zen/zen-1.0_6.html

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 20 '06 #44

This discussion thread is closed

Replies have been disabled for this discussion.