Re: using "!!" in "c"
- From: Flash Gordon <spam@xxxxxxxxxxxxxxxxxx>
- Date: Thu, 19 Jan 2006 14:51:39 +0000
pemo wrote:
"Keith Thompson" <kst-u@xxxxxxx> wrote in message news:lnslrlmlv6.fsf@xxxxxxxxxxxxxxxxxx"pemo" <usenetmeister@xxxxxxxxx> 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. .
- Follow-Ups:
- Re: using "!!" in "c"
- From: pemo
- Re: using "!!" in "c"
- References:
- using "!!" in "c"
- From: markryde
- Re: using "!!" in "c"
- From: pemo
- Re: using "!!" in "c"
- From: Keith Thompson
- Re: using "!!" in "c"
- From: pemo
- using "!!" in "c"
- Prev by Date: Re: String manipulation
- Next by Date: Re: c program binary/image in memory
- Previous by thread: Re: using "!!" in "c"
- Next by thread: Re: using "!!" in "c"
- Index(es):
Relevant Pages
|