-1
struct st  
{  
    int a1 : 3;  
    int a2 : 2;  
    int a3 : 1;  
}

void main(void)
{
    x.a3 = -1;  

    if (x.a3 == -1) printf("TRUE\n");
    else printf("FALSE\n");

    x.a3 = 1;  
    if (x.a3 == 1) printf("TRUE\n");
    else printf("FALSE\n");  
}

In case, 'x.a3 = -1;' First if is TRUE.
But, why 'x.a3 = 1' doesn't changed in second if ? It's still x.a3 = -1.

And
If I type 'x.a3 = 1;' in first if, it still x.a3 = = 1 !! It doesn't changed!

Debug Result in XCode

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
BobKim
  • 9
  • `void main()` is an invalid signature. the minimal signature is `int main(void)`. What is `x`? The code does not compile. Provide a [mcve]. – too honest for this site Apr 17 '17 at 14:08
  • @Olaf As I read C11 5.1.2.2.1 2, "It shall be defined with a return type of int ... or in some other implementation-defined manner." `void main(void)` is implementation-defined if it is valid, not certainly invalid. I suppose it depends on the "or". IAC, certainly not OP's key problem. – chux - Reinstate Monica Apr 18 '17 at 17:28
  • @chux: This is subject to interpretation. Let that apart, all full-size OS require an `int` result. – too honest for this site Apr 18 '17 at 17:34

3 Answers3

3

The problem is, a signed 1 bit variable can hold only two values, -1 and 0 (Read about Two's complement). It is not sufficient to hold a value of 1 (+1, to be exact).

To elaborate, while writing the assignment

 x.a3 = 1;

the value of integer constant 1 is stored into the memory location reserved for the member a3, but while accessing the variable, as per the signedness of the variable (maybe signed or unsigned, implementation defined behaviour, as per chapter §6.7.2/P5), the representation will be read from the memory.

The representation of a stored value of 1 in two's complement, will produce the result -1 (as per MSB value), so a condition check with == 1 will fail, always.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

Because field a3 is a 1 bit int (and therefore signed), it can only hold a value of 0 (if the bit is 0) or -1 (if the bit, which is the sign bit, is 1). So when you attempt to assign the value 1, the representation of that value is stored, and that representation in the given datatype is -1.

Just because the value -1 in a 1-bit int would have the same representation as the value 1 in a 1-bit unsigned int doesn't mean they compare to the same thing.

dbush
  • 205,898
  • 23
  • 218
  • 273
0
int a3 : 1;  

is a struct with a bit field which defines how much space to use to store the var. You are making a1 a one bit signed int, which can only hold the values -1 and 0. If you had intended a3 to hold the value 1, then the syntax you may have intended was int a3 = 1 then one of the many way to do that might look like this

struct st  
{  
    int a1 : 3;  
    int a2 : 2;  
    int a3 : 1;  
};


void main(void)
{
    struct st x = {1,2,3};
    x.a3 = -1;  

    if (x.a3 == -1) printf("TRUE\n");
    else printf("FALSE\n");

    x.a3 = 1;  
    if (x.a3 == 1) printf("TRUE\n");
    else printf("FALSE\n");  
}
gbtimmon
  • 4,238
  • 1
  • 21
  • 36