Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

assigned value has more bits then lvalue

Just out of curiosity. I want to know what happens when the lvalue has less bits then the assigned value.

char a = 0xffffFFFF

Moreover lets say

struct {
int num:3;
}testStruct;

testStruct.num = 0xffffFFFF/2 -1;

what will be the value in char (first case) and 3bit integer (in second case)

like image 794
theadnangondal Avatar asked Dec 29 '14 07:12

theadnangondal


3 Answers

You're using the term "lvalue" incorrectly. I guess you mean "variable" or "object".

In the case sizeof(0xFFFFFFFF) == 1 and plain char being unsigned, then char a = 0xffffFFFF; is straightforward, since that value can be represented in char.

In other cases, it is an out-of-range conversion. If plain char is unsigned then this means the large positive number 0xFFFFFFFF is adjusted modulo UCHAR_MAX+1 to fit (on common systems, the plain char gets 255).

If plain char is signed then it is implementation-defined behaviour (and in C, may raise an implementation-defined signal). The most common implementation definition is 2's complement truncation which would give the char the value -1 but this is not guaranteed.


Moving onto the bitfield. 0xffffFFFF/2 - 1 is 0x7FFFFFFE. This is assigned to a bitfield of type int and width 3, which requests an out-of-range conversion, just like for the signed char case. As before, this is implementation-defined (and may raise an implementation-defined signal in C).

Look up your compiler documentation to find out what it specifies here, although I'd expect again that it would use 2's complement truncation, giving -2.

like image 103
M.M Avatar answered Sep 29 '22 12:09

M.M


The value is preserved if the destination can store the value, else it is reduced modulo CHAR_MAX + 1 if the destination is unsigned, otherwise the result is implementation-defined (C allows trapping though).

char might be able to store 0xFFFFFFFF anyway, if CHAR_BIT is big enough.


C++14 (n3936):

3.9.1 Fundamental types [basic.fundamental]

[...] In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined.

4.7 Integral conversions [conv.integral]

1 A prvalue of an integer type can be converted to a prvalue of another integer type. A prvalue of an unscoped enumeration type can be converted to a prvalue of an integer type.
2 If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type).
3 If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined. 4 If the destination type is bool, see 4.12. If the source type is bool, the value false is converted to zero and the value true is converted to one.
5 The conversions allowed as integral promotions are excluded from the set of integral conversions.


C has rules which have nearly the same result, though observe that the last case may trap.
C11 (C99+amendments) (n1570):

6.2.5 Types

15 The three types char, signed char, and unsigned char are collectively called the character types. The implementation shall define char to have the same range, representation, and behavior as either signed char or unsigned char.45)

6.3.1.3 Signed and unsigned integers

1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.60)
3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

like image 35
Deduplicator Avatar answered Sep 29 '22 11:09

Deduplicator


If value does not fit for integral type (int, char, short, long etc):

  1. Signed: The behaviour is implementation-defined.

  2. Unsigned: Modular value is copied. (i.e. higher bits that can not be stored are ignored while copying)

Please note that char as used in your answer may behave as signed char or unsigned char depending upon your compiler and compilation flags.

what will be the value in char (first case) and 3bit integer (in second case)

The answer is implementation-dependent. Check your compiler documentation for exact answer that suits your environment.

like image 29
Mohit Jain Avatar answered Sep 29 '22 11:09

Mohit Jain