character/byte equality, again

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

Does the code below make any non-portable assumptions other than
CHAR_BIT==8?

char buf[100];

/* do things with buf */

if( !(buf[0]^0xFF) ) /* assume CHAR_BIT is 8 - test for equality */
/* whatever */
 
A

Arthur J. O'Dwyer

Does the code below make any non-portable assumptions other than
CHAR_BIT==8?

char buf[100];

/* do things with buf */

if( !(buf[0]^0xFF) ) /* assume CHAR_BIT is 8 - test for equality */

On a sane implementation, I think this line would always be
equivalent to either

if (buf[0] == (char)0xFF)

or

if ((unsigned char)buf[0] == 0xFFu)

But on an unreasonable yet conforming implementation the evaluation
of (buf[0]^0xFF) could trap, invoking undefined behavior. (On such
implementations, 'char' would necessarily be signed and have one trap
representation.)
In short: I can't think of any use for this construct, and it's
more dangerous than it is helpful, so I would avoid it like the
plague.

-Arthur
 
C

Chris Torek

Does the code below make any non-portable assumptions other than
CHAR_BIT==8?

char buf[100];

/* do things with buf */

if( !(buf[0]^0xFF) ) /* assume CHAR_BIT is 8 - test for equality */

On a sane implementation, I think this line would always be
equivalent to either

if (buf[0] == (char)0xFF)

or

if ((unsigned char)buf[0] == 0xFFu)

Why would you think that?

The operands of the "^" operator are subject to the usual arithmetic
promotions (and constrained to be integers, hence really just the
integer promotions). If plain char is signed, then, and if buf[0]
holds 0xff with CHAR_BIT being 8, buf[0] must be signed and represents
the value -1. Of course, int is at least 16 bits, and a typical
implementation would wind up with the bit pattern 0xffff or 0xffffffff
on the left. The right is just the integer constant 0xff or (int)255,
and the result of the xor is likely to be 0xff00 or 0xffffff00.
But on an unreasonable yet conforming implementation the evaluation
of (buf[0]^0xFF) could trap, invoking undefined behavior. (On such
implementations, 'char' would necessarily be signed and have one trap
representation.)

Yes, this is also possible. I think the fact that it does not
work on most real implementations is more important, though. :)
In short: I can't think of any use for this construct, and it's
more dangerous than it is helpful, so I would avoid it like the
plague.

Indeed.
 
R

Richard Bos

Arthur J. O'Dwyer said:
But on an unreasonable yet conforming implementation the evaluation
of (buf[0]^0xFF) could trap, invoking undefined behavior. (On such
implementations, 'char' would necessarily be signed and have one trap
representation.)

I don't think char is allowed to have trap representations. Unsigned
char certainly isn't, but surely neither is signed char?

Richard
 
A

Arthur J. O'Dwyer

Arthur J. O'Dwyer said:
But on an unreasonable yet conforming implementation the evaluation
of (buf[0]^0xFF) could trap, invoking undefined behavior. (On such
implementations, 'char' would necessarily be signed and have one trap
representation.)

I don't think char is allowed to have trap representations. Unsigned
char certainly isn't, but surely neither is signed char?

I don't see why not. Consider the case of ones' complement signed
char, in which 11111111 ("negative zero") is a trap representation.
Now make plain char signed. :)

-Arthur
 
D

Dan Pop

In said:
The operands of the "^" operator are subject to the usual arithmetic
promotions (and constrained to be integers, hence really just the
integer promotions).

Chris, please use the C terminology correctly.

1. There is no such thing as "usual arithmetic promotions".

2. The integer promotions are limited to types shorter than int. Beyond
that, it is the "usual arithmetic conversions" that operate, even in a
purely integer expression.

Dan
 
P

pete

Arthur said:
Arthur J. O'Dwyer said:
But on an unreasonable yet conforming implementation the evaluation
of (buf[0]^0xFF) could trap, invoking undefined behavior. (On such
implementations, 'char' would necessarily be signed and have one trap
representation.)

I don't think char is allowed to have trap representations. Unsigned
char certainly isn't, but surely neither is signed char?

I don't see why not. Consider the case of ones' complement signed
char, in which 11111111 ("negative zero") is a trap representation.
Now make plain char signed. :)

I believe that it's also possible to have SCHAR_MAX equal 127
and SCHAR_MIN equal -127, when CHAR_BIT is greater than 8.
 
C

Chris Torek

Chris, please use the C terminology correctly.

1. There is no such thing as "usual arithmetic promotions".

2. The integer promotions are limited to types shorter than int. Beyond
that, it is the "usual arithmetic conversions" that operate, even in a
purely integer expression.

Sorry, have not been getting much sleep lately. I knew something was
off even as I wrote that -- but I figured it had been at least a day
and nobody had yet pointed out that the expression did not actually
*work*. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,141
Messages
2,570,815
Members
47,361
Latest member
RogerDuabe

Latest Threads

Top