Quick check on signed promotion of bytes

T

toe

I have a byte called "x". I want byte "y" to be the complement of
"x" (i.e. all the bits flipped).

Initially I wrote:

char unsigned x, y;

...

x = 72;

y = ~x;

But then I thought that the following might happen on your average
system (CHAR_BIT == 8, sizeof(int) == 4):

1) x is promoted to signed int.
2) The complement is take of this signed int.
3) This signed int is then converted to an unsigned char

Am I right in thinking that this is what will happen? If so, would I
be wise to do the following instead:

y = ~(unsigned)x;
 
V

vippstar

I have a byte called "x". I want byte "y" to be the complement of
"x" (i.e. all the bits flipped).

Initially I wrote:

char unsigned x, y;

...

x = 72;

y = ~x;

But then I thought that the following might happen on your average
system (CHAR_BIT == 8, sizeof(int) == 4):

1) x is promoted to signed int.
That won't happend, therefore the rest of your thoughts is false.
Your code is perfectly valid.
 
T

toe

That won't happend, therefore the rest of your thoughts is false.
Your code is perfectly valid.

My understanding was as follows:

"If you're dealing with an integer type smaller than int, then it
must undergo promotion before you can perform any operations on it."
 
E

Eric Sosman

I have a byte called "x". I want byte "y" to be the complement of
"x" (i.e. all the bits flipped).

Initially I wrote:

char unsigned x, y;

...

x = 72;

y = ~x;

But then I thought that the following might happen on your average
system (CHAR_BIT == 8, sizeof(int) == 4):

1) x is promoted to signed int.
2) The complement is take of this signed int.
3) This signed int is then converted to an unsigned char

That's right, under your assumptions. On "exotic" machines
where UCHAR_MAX > INT_MAX (for example, on hardware where all
of char, short, and int are 16 bits wide), then x promotes to
an unsigned int instead of to an int in step 1.

Also see vippstar's response: It's wrong.
Am I right in thinking that this is what will happen? If so, would I
be wise to do the following instead:

y = ~(unsigned)x;

Yes, this will work on both "exotic" and "humdrum" machines.
 
T

Tomás Ó hÉilidhe

Eric Sosman:
That's right, under your assumptions. On "exotic" machines
where UCHAR_MAX > INT_MAX (for example, on hardware where all
of char, short, and int are 16 bits wide), then x promotes to
an unsigned int instead of to an int in step 1.


So just to confirm if I'm thinking right. We start off with:

char unsigned x, y;

x = 0xf0;

y = ~x;

What we _want_ this code to do is to give us the value 0x0f for y (i.e.
the complement of x). However what _could_ happen is:

1) x is promoted to signed int.

=> Now we have a signed int with the value 0xf0

2) The complement is taken of this signed int.

=> Now we have some other number that is negative. The exact number
depends on the number system in use (e.g. sign-magnitude), and
also the amount of bits in an int.

3) The signed int is converted to an unsigned char.

=> This process is well-defined, but we don't know what signed
value we have.

Therefore, it is my assumption that will not give the desired behaviour
on every implementation of the Standard -- we could get something
totally different from 0x0f as an answer (even on an 8-bit-byte system).

That sound right?
 
E

Eric Sosman

Tomás Ó hÉilidhe said:
Eric Sosman:



So just to confirm if I'm thinking right. We start off with:

char unsigned x, y;

x = 0xf0;

y = ~x;

What we _want_ this code to do is to give us the value 0x0f for y (i.e.
the complement of x). However what _could_ happen is:

1) x is promoted to signed int.

=> Now we have a signed int with the value 0xf0

2) The complement is taken of this signed int.

=> Now we have some other number that is negative. The exact number
depends on the number system in use (e.g. sign-magnitude), and
also the amount of bits in an int.

3) The signed int is converted to an unsigned char.

=> This process is well-defined, but we don't know what signed
value we have.

Therefore, it is my assumption that will not give the desired behaviour
on every implementation of the Standard -- we could get something
totally different from 0x0f as an answer (even on an 8-bit-byte system).

That sound right?

Sounds right to me. The list of potential negative values
is long but "sparse:" two's complement and ones' complement give
-241 and -240, respectively, while signed magnitude gives one of
-0x7f0f, -0xff0f, -0x1ff0f, ... depending on the number of value
bits in an int.
 
V

vippstar

That's right, under your assumptions. On "exotic" machines
where UCHAR_MAX > INT_MAX (for example, on hardware where all
of char, short, and int are 16 bits wide), then x promotes to
an unsigned int instead of to an int in step 1.

Also see vippstar's response: It's wrong.
Ah, I apologise, just something i am not sure about, char unsigned x,
y; means unsigned char x, 'plain' char y?
 
S

santosh

Ah, I apologise, just something i am not sure about, char unsigned x,
y; means unsigned char x, 'plain' char y?

No, it's equivalent to:

unsigned char x;
unsigned char y;
 
E

Eric Sosman

Ah, I apologise, just something i am not sure about, char unsigned x,
y; means unsigned char x, 'plain' char y?

`char unsigned' means the same thing as `unsigned char';
the order of the keywords in a multi-keyword type specifier
doesn't matter. So `char unsigned x, y;' means the same thing
as `unsigned char x, y;' and gives both x and y the same type.

Win pocket money by writing `long int signed long x;'
or `double long y;' and betting the boys at the bar that
it's legal C.
 
J

Jack Klein

That won't happend, therefore the rest of your thoughts is false.
Your code is perfectly valid.

No, your correction is false. 'x' must be promoted to either signed
or unsigned int before the bitwise inversion operator is applies. In
a system with CHAR_BIT is 8, a signed int must be able to hold all
possible values of unsigned char, so 'x' is indeed promoted to signed
int.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top