Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

!!, what is it?

0 views
Skip to first unread message

bjk of course

unread,
Sep 11, 2005, 10:49:17 AM9/11/05
to
hello,

I've stumbled upon this in some code:

n = !!x;

I've ran it and 'n' is always either 0 or 1. Is '!!' an operator (what's it
called?) and is it standard/portable?

--
b e n k i b b e y ::: bjk AT arbornet DOT org

Alexei A. Frounze

unread,
Sep 11, 2005, 11:06:07 AM9/11/05
to
"bjk of course" <Use-Author-Supplied-Address-Header@[127.1]> wrote in
message news:20050911144...@cpe-66-1-217-9.fl.sprintbbd.net...

> hello,
>
> I've stumbled upon this in some code:
>
> n = !!x;
>
> I've ran it and 'n' is always either 0 or 1. Is '!!' an operator (what's
it
> called?) and is it standard/portable?

n = !!x;
should be equivalent to:
n = !(!x);
or even:
n = !(!(x));

And n should be 1 if x is nonzero, 0 if x is zero.

Got the idea?

Alex


Mike Wahler

unread,
Sep 11, 2005, 11:07:53 AM9/11/05
to
"bjk of course" <Use-Author-Supplied-Address-Header@[127.1]> wrote in
message news:20050911144...@cpe-66-1-217-9.fl.sprintbbd.net...
> hello,
>
> I've stumbled upon this in some code:
>
> n = !!x;
>
> I've ran it and 'n' is always either 0 or 1.

Yes, because that's always the result of the ! ("logical not")
operator.

> Is '!!' an operator

No, ! is an operator. It's result is always either zero or one.
It is simply being used twice in the above code. E.g.

!0 == 1
!1 == 0
!42 == 0;
!!42 == 1 /* because !42 == 0, then !(!42) == 1
(because !0 == 1) */


etc.

>(what's it
> called?)

"Logical not".

>and is it standard/portable?

Yes.

int i = 42;
int j = !i; /* initializes 'j' with 0 */
int k; = !!i; /* initializes 'k' with 1 */
int m = !j; /* initializes 'm' with 1 */

The typical reason for this 'double application' of the logical
not operator is to transform a nonzero value (which logically
always evaluates to 'true') into a specific 'true' value (in
this case one (1). The reason for needing to do this depends
upon the application. Here's a simple contrived example:

#include <stdio.h>

/* zero value is invalid, any nonzero value is valid */
void validate(int value)
{
static const char *msg[] = {"invalid", "valid"};
printf("value %d is %s\n", msg[!!i]);
/* note that !!0 always is exactly 0 */
}

int main()
{
validate(42);
return 0;
}

IOW, !42 == 0 , !!42 == 1 , !!42 != 42

If some other specific 'true' value were needed, one would
simply perform more arithmetic upon the value one (e.g. add
some value).

-Mike


DevarajA

unread,
Sep 11, 2005, 11:09:04 AM9/11/05
to
bjk of course ha scritto:

> hello,
>
> I've stumbled upon this in some code:
>
> n = !!x;
>
> I've ran it and 'n' is always either 0 or 1. Is '!!' an operator (what's it
> called?) and is it standard/portable?
>

It means 'not not x', evaluating to 0 if x is 0 or to 1 if x is not 0.

--
Devaraja (Xdevaraja87^gmail^c0mX)
Linux Registerd User #338167
http://counter.li.org

Mike Wahler

unread,
Sep 11, 2005, 11:13:15 AM9/11/05
to

"Mike Wahler" <mkwa...@mkwahler.net> wrote in message
news:dLXUe.8731$4P5....@newsread2.news.pas.earthlink.net...

> #include <stdio.h>
>
> /* zero value is invalid, any nonzero value is valid */
> void validate(int value)
> {
> static const char *msg[] = {"invalid", "valid"};
> printf("value %d is %s\n", msg[!!i]);

Oops, should be
printf("value %d is %s\n", msg[!!value]);


Cafer Şimşek

unread,
Sep 11, 2005, 12:14:22 PM9/11/05
to
"Mike Wahler" <mkwa...@mkwahler.net> writes:


[...]

> No, ! is an operator. It's result is always either zero or one.

^^^^^^^^^^^^

I think, C standarts says something about logical operations resusts;
if the result is false, it's value is 0 (zero). if the result is true,
it's value is non-zero (like -2, -1, 2, 3, ...). So, it must NOT be
one. This difference has seen according to compiler or target
platform.

For example; some compiler's headers provide TRUE and FALSE constants
like that;

#define FALSE 0
#define TRUE !FALSE

// or

#define TRUE (0==0)
#define FALSE !TRUE


[...]

Best Regards.

--
Cafer Şimşek
http://cafer.org

Cafer Şimşek

unread,
Sep 11, 2005, 12:16:31 PM9/11/05
to
ca...@gawab.com (Cafer Şimşek) writes:

> "Mike Wahler" <mkwa...@mkwahler.net> writes:
>
>
> [...]
>
>> No, ! is an operator. It's result is always either zero or one.
> ^^^^^^^^^^^^
>
> I think, C standarts says something about logical operations resusts;
> if the result is false, it's value is 0 (zero). if the result is true,
> it's value is non-zero (like -2, -1, 2, 3, ...). So, it must NOT be

^^^^
may

Irrwahn Grausewitz

unread,
Sep 11, 2005, 12:35:27 PM9/11/05
to
ca...@gawab.com (Cafer ?im?ek) wrote:

>ca...@gawab.com (Cafer ?im?ek) writes:
>> "Mike Wahler" <mkwa...@mkwahler.net> writes:
>> [...]
>>> No, ! is an operator. It's result is always either zero or one.

Correct.

>> I think, C standarts says something about logical operations resusts;

It does.

>> if the result is false, it's value is 0 (zero).

Correct.

>>if the result is true,
>> it's value is non-zero (like -2, -1, 2, 3, ...). So, it must NOT be
> ^^^^
> may
>> one.

Wrong, see quote below..

>> This difference has seen according to compiler or target
>> platform.

Then those implementations are not conforming. Consider:

ISO/IEC 9899:1999 (E)

6.5.3.3p5
The result of the logical negation operator ! is 0 if the value of
its operand compares unequal to 0, 1 if the value of its operand
compares equal to 0. The result has type int. The expression !E is
equivalent to (0==E).

6.5.9p3
The == (equal to) and != (not equal to) operators are analogous to
the relational operators except for their lower precedence. Each of
the operators yields 1 if the specified relation is true and 0 if it
is false. The result has type int. For any pair of operands, exactly
one of the relations is true.

Similar semantics apply to the other logical operators (&& and ||),
and the relational operators (<, >, <=, >=).

Best regards.
--
Irrwahn Grausewitz (irrw...@freenet.de)
welcome to clc : http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc frequent answers: http://benpfaff.org/writings/clc

Mike Wahler

unread,
Sep 11, 2005, 12:58:25 PM9/11/05
to

"Cafer "Simsek"" <ca...@gawab.com> wrote in message
news:87irx7wp...@gawab.com...

> ca...@gawab.com (Cafer Simsek) writes:
>
>> "Mike Wahler" <mkwa...@mkwahler.net> writes:
>>
>>
>> [...]
>>
>>> No, ! is an operator. It's result is always either zero or one.
>> ^^^^^^^^^^^^
>>
>> I think, C standarts says something about logical operations resusts;

Yes.

>> if the result is false, it's value is 0 (zero). if the result is true,
>> it's value is non-zero (like -2, -1, 2, 3, ...). So, it must NOT be
> ^^^^
> may

This is not what the C standard states.

>> one. This difference has seen according to compiler or target
>> platform.

Compilers don't dictate the rules (they can sometimes incorrectly implement
them
however). The C standard (ISO 9899) makes the language rules.


>>
>> For example; some compiler's headers provide TRUE and FALSE constants
>> like that;

..doesn't change the rules.

>>
>> #define FALSE 0
>> #define TRUE !FALSE

This means the macro 'TRUE' will *always* yield the *exact*
value of 1. (!0 == 1, always).


>>
>> // or
>>
>> #define TRUE (0==0)

Always has exact value of one.

>> #define FALSE !TRUE

Always has exact value of zero.

-Mike


Keith Thompson

unread,
Sep 11, 2005, 1:34:28 PM9/11/05
to
ca...@gawab.com (Cafer Şimşek) writes:
[...]

> For example; some compiler's headers provide TRUE and FALSE constants
> like that;
>
> #define FALSE 0
> #define TRUE !FALSE
>
> // or
>
> #define TRUE (0==0)
> #define FALSE !TRUE

If you want to define symbols TRUE and FALSE, just use:

#define TRUE 1
#define FALSE 0

There is no advantage to be gained from using more complex expressions.

See section 9 of the C FAQ.

--
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.

Flash Gordon

unread,
Sep 11, 2005, 2:15:46 PM9/11/05
to
Cafer Şimşek wrote:
> "Mike Wahler" <mkwa...@mkwahler.net> writes:
>
>
> [...]
>
>
>>No, ! is an operator. It's result is always either zero or one.
>
> ^^^^^^^^^^^^
>
> I think, C standarts says something about logical operations resusts;
> if the result is false, it's value is 0 (zero). if the result is true,
> it's value is non-zero (like -2, -1, 2, 3, ...). So, it must NOT be
> one. This difference has seen according to compiler or target
> platform.

Incorrect. The result of any logical operator is *always* 0 or 1 and
this is defined by the standard. What probably has you confused is that
any non-zero value will act as true, so all the values you quote will
act as true. However, I repeat, the boolean operators will never return
any value other than 0 or 1 on *any* implementation.

> For example; some compiler's headers provide TRUE and FALSE constants
> like that;
>
> #define FALSE 0
> #define TRUE !FALSE
>
> // or
>
> #define TRUE (0==0)
> #define FALSE !TRUE

In both cases you are guaranteed that TRUE == 1.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.

Charlie Gordon

unread,
Sep 11, 2005, 8:04:33 PM9/11/05
to
"Keith Thompson" <ks...@mib.org> wrote in message
news:lnoe6z4...@nuthaus.mib.org...

> ca...@gawab.com (Cafer Şimşek) writes:
> [...]
> > For example; some compiler's headers provide TRUE and FALSE constants
> > like that;
> >
> > #define FALSE 0
> > #define TRUE !FALSE
> >
> > // or
> >
> > #define TRUE (0==0)
> > #define FALSE !TRUE
>
> If you want to define symbols TRUE and FALSE, just use:
>
> #define TRUE 1
> #define FALSE 0
>
> There is no advantage to be gained from using more complex expressions.
>
> See section 9 of the C FAQ.

As a matter of fact, the above definitions could cause bugs because the macro
expansion is not correctly parenthesized. Here is a contorted example:

#define FALSE 0
#define TRUE !FALSE

char c = FALSE["FT"]; // sets c to 'F'
char c = TRUE["FT"]; // sets c to 0 instead of 'T'

--
Chqrlie.


Kenneth Brody

unread,
Sep 11, 2005, 9:10:21 PM9/11/05
to
Flash Gordon wrote:
>
> Cafer Şimşek wrote:
[...]

> > I think, C standarts says something about logical operations resusts;
> > if the result is false, it's value is 0 (zero). if the result is true,
> > it's value is non-zero (like -2, -1, 2, 3, ...). So, it must NOT be
> > one. This difference has seen according to compiler or target
> > platform.
>
> Incorrect. The result of any logical operator is *always* 0 or 1 and
> this is defined by the standard. What probably has you confused is that
> any non-zero value will act as true, so all the values you quote will
> act as true. However, I repeat, the boolean operators will never return
> any value other than 0 or 1 on *any* implementation.
[...]

Well, any C89 or later, I assume. I've worked on platforms (prior to
1989) where boolean expressions were 0 or -1.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:ThisIsA...@gmail.com>

Charlie Gordon

unread,
Sep 11, 2005, 10:02:17 PM9/11/05
to
"Kenneth Brody" <kenb...@spamcop.net> wrote in message
news:4324D57D...@spamcop.net...
> Flash Gordon wrote:

> >
> > Cafer ÅzimÅYek wrote:
> [...]
> > > I think, C standarts says something about logical operations resusts;
> > > if the result is false, it's value is 0 (zero). if the result is true,
> > > it's value is non-zero (like -2, -1, 2, 3, ...). So, it must NOT be
> > > one. This difference has seen according to compiler or target
> > > platform.
> >
> > Incorrect. The result of any logical operator is *always* 0 or 1 and
> > this is defined by the standard. What probably has you confused is that
> > any non-zero value will act as true, so all the values you quote will
> > act as true. However, I repeat, the boolean operators will never return
> > any value other than 0 or 1 on *any* implementation.
> [...]
>
> Well, any C89 or later, I assume. I've worked on platforms (prior to
> 1989) where boolean expressions were 0 or -1.

You must have been programming in Basic!

No C implementation ever used -1 as the value of 0==0

One other explanation for this misunderstanding is that you may have been using
1 bit bitfields: it is implementation defined whether these have values 0 and 1
or 0 and -1. As far as I recall, C99 did not change that.

--
Chqrlie.


Michael Mair

unread,
Sep 12, 2005, 3:36:01 AM9/12/05
to
Charlie Gordon wrote:
> "Kenneth Brody" <kenb...@spamcop.net> wrote in message
> news:4324D57D...@spamcop.net...
>
>>Flash Gordon wrote:
>>
>>>Cafer ĹzimĹYek wrote:
>>
>>[...]
>>
>>>>I think, C standarts says something about logical operations resusts;
>>>>if the result is false, it's value is 0 (zero). if the result is true,
>>>>it's value is non-zero (like -2, -1, 2, 3, ...). So, it must NOT be
>>>>one. This difference has seen according to compiler or target
>>>>platform.
>>>
>>>Incorrect. The result of any logical operator is *always* 0 or 1 and
>>>this is defined by the standard. What probably has you confused is that
>>>any non-zero value will act as true, so all the values you quote will
>>>act as true. However, I repeat, the boolean operators will never return
>>>any value other than 0 or 1 on *any* implementation.
>>
>>[...]
>>
>>Well, any C89 or later, I assume. I've worked on platforms (prior to
>>1989) where boolean expressions were 0 or -1.
>
> You must have been programming in Basic!
>
> No C implementation ever used -1 as the value of 0==0

As an aside:
I recall seeing some platform specific headers which went for the
all-bits-one representation of "true" -- but the C implementations
gave 1 for !!TRUE as well...


> One other explanation for this misunderstanding is that you may have been using
> 1 bit bitfields: it is implementation defined whether these have values 0 and 1
> or 0 and -1. As far as I recall, C99 did not change that.

Naive question after having a look at C99, 6.7.2.1:
Does this ambiguity only hold for "int" bitfields or also for
"signed int" bitfields?

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.

Tim Woodall

unread,
Sep 12, 2005, 6:44:05 PM9/12/05
to
On Mon, 12 Sep 2005 09:36:01 +0200,
Michael Mair <Michae...@invalid.invalid> wrote:
>
> As an aside:
> I recall seeing some platform specific headers which went for the
> all-bits-one representation of "true" -- but the C implementations
> gave 1 for !!TRUE as well...
>
>
int is_it_seven(int x)
{
return x==7;
}

if(is_it_seven(7) == TRUE)
printf("7 is seven\n");
else
printf("7 is not seven\n");

While I would never write the explicit test for TRUE [1], I would be
horrified at any header that defined TRUE such that this code didn't
behave as expected.

[1] Other peoples coding standards excepted.

>> One other explanation for this misunderstanding is that you may have been using
>> 1 bit bitfields: it is implementation defined whether these have values 0 and 1
>> or 0 and -1. As far as I recall, C99 did not change that.
>
> Naive question after having a look at C99, 6.7.2.1:
> Does this ambiguity only hold for "int" bitfields or also for
> "signed int" bitfields?
>

If you are using sign-magnitude or ones complement encoding then the
possible values of a signed int bitfield will be +0 and -0 or 0 and a
trap representation.

(I hope there isn't something somewhere that says that bitfields must be
twos complement. I can't see it but I'm sure if there is someone here
will be along quickly to correct me. ;-) )

Tim.

--
God said, "div D = rho, div B = 0, curl E = - @B/@t, curl H = J + @D/@t,"
and there was light.

http://tjw.hn.org/ http://www.locofungus.btinternet.co.uk/

Gordon Burditt

unread,
Sep 12, 2005, 7:06:59 PM9/12/05
to
>> I recall seeing some platform specific headers which went for the
>> all-bits-one representation of "true" -- but the C implementations
>> gave 1 for !!TRUE as well...
>>
>>
>int is_it_seven(int x)
>{
> return x==7;
>}
>
>if(is_it_seven(7) == TRUE)

This, of course, is more correctly written as
if ((is_it_seven(7) == TRUE) == TRUE)
which should be rewritten as:
if (((is_it_seven(7) == TRUE) == TRUE) == TRUE)

> printf("7 is seven\n");
>else
> printf("7 is not seven\n");
>
>While I would never write the explicit test for TRUE [1], I would be
>horrified at any header that defined TRUE such that this code didn't
>behave as expected.

While in this case there IS a definition of TRUE which will "do as
expected", there may not be in the case of functions other than
is_it_seven, such as the <ctype.h> functions like isalpha() and
ispunct(), which are *NOT* guaranteed to produce only 0 or 1.

Gordon L. Burditt

Keith Thompson

unread,
Sep 12, 2005, 7:29:18 PM9/12/05
to
Tim Woodall <dev...@woodall.me.uk> writes:
> On Mon, 12 Sep 2005 09:36:01 +0200,
> Michael Mair <Michae...@invalid.invalid> wrote:
>>
>> As an aside:
>> I recall seeing some platform specific headers which went for the
>> all-bits-one representation of "true" -- but the C implementations
>> gave 1 for !!TRUE as well...
>>
>>
> int is_it_seven(int x)
> {
> return x==7;
> }
>
> if(is_it_seven(7) == TRUE)
> printf("7 is seven\n");
> else
> printf("7 is not seven\n");
>
> While I would never write the explicit test for TRUE [1], I would be
> horrified at any header that defined TRUE such that this code didn't
> behave as expected.
>
> [1] Other peoples coding standards excepted.

The way to avoid this problem is to avoid *ever* doing an equality or
inequality comparison against either TRUE or FALSE. It happens that
FALSE can only be 0 (assuming sanity on the part of the author), so
(whatever == FALSE) is probably safe, but it's easier to remember and
follow the more general rule.

Remember that the is*() functions in <ctype.h> are explicitly allowed
to return non-zero values, so even with TRUE defined as 1, the test
(isalpha(c) == TRUE) is broken.

If you're going to define FALSE and TRUE, there's no reason to use
values other than FALSE==0 and TRUE==1. (Note that C99's <stdbool.h>
has false==0 and true==1.) But if you're going to write
if (is_it_seven(7) == TRUE) ...
you might as well write
if (((is_it_seven(7) == TRUE) != FALSE) == TRUE) ...

Or just do it right:
if (is_it_seven(7)) ...

There's no reason why one unnecessary comparison is better than two or
more. There's only one logical place to stop adding comparisons, and
that's before the first one.

The relational operators are defined to yield 0 or 1; if they don't,
the compiler is broken. But code that depends on this, though valid,
is suspicious; it's too easy to change
count += (x == 42);
to
count += (nearly_equal(x, 42));
and miss the fact that nearly_equal can return -1.

[...]


> If you are using sign-magnitude or ones complement encoding then the
> possible values of a signed int bitfield will be +0 and -0 or 0 and a
> trap representation.
>
> (I hope there isn't something somewhere that says that bitfields must be
> twos complement. I can't see it but I'm sure if there is someone here
> will be along quickly to correct me. ;-) )

No, bit fields aren't required to be two's complement, so there's no
guarantee that a 1-bit signed bit field can hold a value other than 0.
But signed bit fields in general are unlikely to be useful. That's
not to say that they're never useful. If you want a struct member to
be as small as possible and to hold any value in the range -7..+7, a
4-bit signed bit field is the way to do it. But as soon as you try to
store -8, you've lost some portability. (Then again, a restriction to
2's-complement systems may not be a problem.)

Michael Mair

unread,
Sep 13, 2005, 3:12:42 AM9/13/05
to
Tim Woodall wrote:
> On Mon, 12 Sep 2005 09:36:01 +0200,
> Michael Mair <Michae...@invalid.invalid> wrote:
>
>>As an aside:
>>I recall seeing some platform specific headers which went for the
>>all-bits-one representation of "true" -- but the C implementations
>>gave 1 for !!TRUE as well...
>
> int is_it_seven(int x)
> {
> return x==7;
> }
>
> if(is_it_seven(7) == TRUE)
> printf("7 is seven\n");
> else
> printf("7 is not seven\n");
>
> While I would never write the explicit test for TRUE [1], I would be
> horrified at any header that defined TRUE such that this code didn't
> behave as expected.
>
> [1] Other peoples coding standards excepted.

Sorry, without C99's _Bool and _True, this argument is bogus.
Apart from the possible range of return values one could expect from
is_it_seven() and the possible mismatch with, say isalnum() == TRUE
or strcmp() != TRUE, there is no benefit in that.
IIRC, this "TRUE" was intended for bitwise operations and conveniently
fulfilled !TRUE == FALSE. However, this would not have worked on a
1s complement platform.

>>>One other explanation for this misunderstanding is that you may have been using
>>>1 bit bitfields: it is implementation defined whether these have values 0 and 1
>>>or 0 and -1. As far as I recall, C99 did not change that.
>>
>>Naive question after having a look at C99, 6.7.2.1:
>>Does this ambiguity only hold for "int" bitfields or also for
>>"signed int" bitfields?
>
> If you are using sign-magnitude or ones complement encoding then the
> possible values of a signed int bitfield will be +0 and -0 or 0 and a
> trap representation.
>
> (I hope there isn't something somewhere that says that bitfields must be
> twos complement. I can't see it but I'm sure if there is someone here
> will be along quickly to correct me. ;-) )

Sorry, I probably did not phrase it carefully enough.

This was not my question. I am well aware of s-m and 1s complement,
my question more or less is whether it is possible that a signed
int bitfield could be treated as if it was an unsigned int
bitfield?

Here some context; see especially the footnote:

"
6.7.2.1:

4 A bit-field shall have a type that is a qualified or unqualified
version of _Bool, signed int, unsigned int, or some other
implementation-defined type.

Semantics
[...]
8 A member of a structure or union may have any object type other
than a variably modified type.102)
In addition, a member may be declared to consist of a specified
number of bits (including a sign bit, if any). Such a member is
called a bit-field;103) its width is preceded by a colon.
9 A bit-field is interpreted as a signed or unsigned integer type
consisting of the specified number of bits.104) If the value 0 or
1 is stored into a nonzero-width bit-field of type _Bool, the
value of the bit-field shall compare equal to the value stored.
____
104) As specified in 6.7.2 above, if the actual type specifier
used is int or a typedef-name defined as int, then it is
implementation-defined whether the bit-field is signed or unsigned.

Tim Woodall

unread,
Sep 14, 2005, 4:01:12 PM9/14/05
to
On Tue, 13 Sep 2005 09:12:42 +0200,

Michael Mair <Michae...@invalid.invalid> wrote:
> Tim Woodall wrote:
>> On Mon, 12 Sep 2005 09:36:01 +0200,
>> Michael Mair <Michae...@invalid.invalid> wrote:
>>
>>>As an aside:
>>>I recall seeing some platform specific headers which went for the
>>>all-bits-one representation of "true" -- but the C implementations
>>>gave 1 for !!TRUE as well...
>>
>> int is_it_seven(int x)
>> {
>> return x==7;
>> }
>>
>> if(is_it_seven(7) == TRUE)
>> printf("7 is seven\n");
>> else
>> printf("7 is not seven\n");
>>
>> While I would never write the explicit test for TRUE [1], I would be
>> horrified at any header that defined TRUE such that this code didn't
>> behave as expected.
>>
>> [1] Other peoples coding standards excepted.
>
> Sorry, without C99's _Bool and _True, this argument is bogus.
> Apart from the possible range of return values one could expect from
> is_it_seven() and the possible mismatch with, say isalnum() == TRUE
> or strcmp() != TRUE, there is no benefit in that.
I KNOW there is no benefit in that. Thats why I wrote

"While I would never write the explicit test for TRUE"

But I would not pass review any C source that defined FALSE as anything
other than 0 and TRUE as anything other than 1 (or some equivalent
expression)

Infact, assuming I spotted it, I wouldn't accept any code that had a
function commented /* returns TRUE or FALSE */ unless the function
returned only 1 or 0 regardless of whether the macros TRUE and FALSE
were actually defined


> IIRC, this "TRUE" was intended for bitwise operations and conveniently
> fulfilled !TRUE == FALSE. However, this would not have worked on a
> 1s complement platform.

I still wouldn't have accepted it. There will have been a better name
for the macro.


> Sorry, I probably did not phrase it carefully enough.
>
> This was not my question. I am well aware of s-m and 1s complement,
> my question more or less is whether it is possible that a signed
> int bitfield could be treated as if it was an unsigned int
> bitfield?
>

No. (IMO) 6.7.2.1

9 A bit-field is interpreted as a signed or unsigned integer type ...

and then footnote 104) paraphrased - if the type specifier is int it is
implementation defined whether the bitfield is signed or unsigned

Which implies to me that signed int -> signed, unsigned int -> unsigned
and int goes to one or the other.

Michael Mair

unread,
Sep 14, 2005, 4:42:49 PM9/14/05
to

We certainly agree on that and I did not mean to imply that you did
not know that there is no benefit.

However, this does not change the fact that "true" in C prior to
C99 is everything which is not zero. To underline this, I mentioned
this particular definition of true.


>>IIRC, this "TRUE" was intended for bitwise operations and conveniently
>>fulfilled !TRUE == FALSE. However, this would not have worked on a
>>1s complement platform.
>
> I still wouldn't have accepted it. There will have been a better name
> for the macro.

Definitely.
Knowing a better way does not help all the time. I often
enough come across the mess of "somebody whose successor
left the company some years ago" or similar without the
opportunity to fix it (ROI). So, sometimes you have to
live with the way things have to be done and do the best
to wrap the ugliness and do it better.


>>Sorry, I probably did not phrase it carefully enough.
>>
>>This was not my question. I am well aware of s-m and 1s complement,
>>my question more or less is whether it is possible that a signed
>>int bitfield could be treated as if it was an unsigned int
>>bitfield?
>
> No. (IMO) 6.7.2.1
>
> 9 A bit-field is interpreted as a signed or unsigned integer type ...
>
> and then footnote 104) paraphrased - if the type specifier is int it is
> implementation defined whether the bitfield is signed or unsigned
>
> Which implies to me that signed int -> signed, unsigned int -> unsigned
> and int goes to one or the other.

Thank you for your opinion on that. This is my reading too.
Unfortunately, I have been wrong often enough concerning the
standard.

Tim Rentsch

unread,
Sep 14, 2005, 6:16:20 PM9/14/05
to
Tim Woodall <dev...@woodall.me.uk> writes:

> On Tue, 13 Sep 2005 09:12:42 +0200,
> Michael Mair <Michae...@invalid.invalid> wrote:

[snip]


> > This was not my question. I am well aware of s-m and 1s complement,
> > my question more or less is whether it is possible that a signed
> > int bitfield could be treated as if it was an unsigned int
> > bitfield?
> >
> No. (IMO) 6.7.2.1
>
> 9 A bit-field is interpreted as a signed or unsigned integer type ...
>
> and then footnote 104) paraphrased - if the type specifier is int it is
> implementation defined whether the bitfield is signed or unsigned
>
> Which implies to me that signed int -> signed, unsigned int -> unsigned
> and int goes to one or the other.

It is possible for a signed int bitfield to behave as though
it holds an unsigned int bitfield value.

On a one-bit bitfield, for example, an implementation could
define 0 as "zero" and 1 as "trap representation". Storing
any non-zero value into the bitfield would result in a trap
representation, which can do anything because of undefined
behavior. In particular, storing a 1 could later result in
a 1 being produced.

A multi-bit bitfield could have all "negative values" be
trap representations. Sort of weird, but it's allowed. At
least, I haven't found any language in the Standard that
disallows it. The particular case of a non-zero being
stored in a 1-bit bitfield is explicitly allowed (in section
6.2.6.2 p2); it does at least have to be explicitly
identified by the implementation.

Because of the wonders of undefined behavior, it's also
possible to mix and match. For example:

struct {
signed int a:1;
signed int b:1;
} bits;

bits.a = 1;
bits.b = -1;
printf( "a: %d b: %d\n", bits.a, bits.b );

could very well print "a: 1 b: -1" as its output. Something
like this might happen if a compiler did some dataflow
analysis and determined that the 'a' field is used to hold
1's and 0's and the 'b' field is used to hold 0's and -1's.
Once some evaluation results in a trap representation being
stored, any behavior is possible -- it doesn't have to be
consistent from variable to variable.

Emlyn Corrin

unread,
Sep 16, 2005, 5:12:21 AM9/16/05
to

"Michael Mair" <Michae...@invalid.invalid> wrote in message
news:3oncfnF...@individual.net...

> Tim Woodall wrote:
>> On Mon, 12 Sep 2005 09:36:01 +0200,
>> Michael Mair <Michae...@invalid.invalid> wrote:
>>
>>>As an aside:
>>>I recall seeing some platform specific headers which went for the
>>>all-bits-one representation of "true" -- but the C implementations
>>>gave 1 for !!TRUE as well...
>>
> IIRC, this "TRUE" was intended for bitwise operations and conveniently
> fulfilled !TRUE == FALSE.

As would any other non-zero value,
and it won't fulfill !FALSE == TRUE.

Emlyn


Charlie Gordon

unread,
Sep 16, 2005, 12:42:11 PM9/16/05
to
"Tim Rentsch" <t...@alumnus.caltech.edu> wrote in message
news:kfn7jdj...@alumnus.caltech.edu...

> Tim Woodall <dev...@woodall.me.uk> writes:
>
> > On Tue, 13 Sep 2005 09:12:42 +0200,
> > Michael Mair <Michae...@invalid.invalid> wrote:
> [snip]
> > > This was not my question. I am well aware of s-m and 1s complement,
> > > my question more or less is whether it is possible that a signed
> > > int bitfield could be treated as if it was an unsigned int
> > > bitfield?
> > >
> > No. (IMO) 6.7.2.1
> >
> > 9 A bit-field is interpreted as a signed or unsigned integer type ...
> >
> > and then footnote 104) paraphrased - if the type specifier is int it is
> > implementation defined whether the bitfield is signed or unsigned
> >
> > Which implies to me that signed int -> signed, unsigned int -> unsigned
> > and int goes to one or the other.
>
> It is possible for a signed int bitfield to behave as though
> it holds an unsigned int bitfield value.
>
> On a one-bit bitfield, for example, an implementation could
> define 0 as "zero" and 1 as "trap representation". Storing
> any non-zero value into the bitfield would result in a trap
> representation, which can do anything because of undefined
> behavior. In particular, storing a 1 could later result in
> a 1 being produced.

This is quite unlikely, possibly even completely virtual at this point.
Could you give an example of compiler/cpu combination where this occurs ?

> A multi-bit bitfield could have all "negative values" be
> trap representations. Sort of weird, but it's allowed. At
> least, I haven't found any language in the Standard that
> disallows it. The particular case of a non-zero being
> stored in a 1-bit bitfield is explicitly allowed (in section
> 6.2.6.2 p2); it does at least have to be explicitly
> identified by the implementation.

Which version of the standard are you referring to ? Mine doesn't mention
bit-fields in 6.2.6.2 p2.
It doesn't disallow it but doesn't go into detail about the case of a signed
value consisting of just its sign bit (precision=0).
Could you please quote the paragraph?

> Because of the wonders of undefined behavior, it's also
> possible to mix and match. For example:
>
> struct {
> signed int a:1;
> signed int b:1;
> } bits;
>
> bits.a = 1;
> bits.b = -1;
> printf( "a: %d b: %d\n", bits.a, bits.b );
>
> could very well print "a: 1 b: -1" as its output. Something
> like this might happen if a compiler did some dataflow
> analysis and determined that the 'a' field is used to hold
> 1's and 0's and the 'b' field is used to hold 0's and -1's.
> Once some evaluation results in a trap representation being
> stored, any behavior is possible -- it doesn't have to be
> consistent from variable to variable.

Really ? I would expect such a smart compiler to issue a warning about the
programmer's inconsistency.
Re-reading the Standard, I don't see any indication that supports your claim.
It is implementation defined whether int bitfields are interpreted as signed or
unsigned, but no language indicates any restriction regarding signed int
bitfields. whether these can represent just 0 or 0 and -1 is implementation
defined, but not undefined behaviour.

--
Chqrlie.


0 new messages