pemo said:
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.
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.
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.)