-5

I am an amateur C programmer and I encountered this question in a book,can someone give me its valid explanation. I am getting confused as to what this ^ sign is doing in a C program.

#include <stdio.h>

int main(void)
{
    int a;
    printf("%d", (3^6) + (a^a));
    return 0;
}
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    It is a [XOR](http://en.wikipedia.org/wiki/C_operators#Bitwise_operators) operator. – Kninnug Nov 30 '13 at 13:13
  • 7
    "I am getting confused as to what this ^ sign is doing in a C program" - then why don't you google "C operators"? The first hit is the Wikipedia page called "Operators in C and C++", and - unsurprisingly - it addresses this particular operator as well. Or you could just read a tutorial that explains mathematical operators. –  Nov 30 '13 at 13:15
  • what does your program do ? does it print 5. Lucky if a was 0, otherwise its not initialised, holds a garbage value and you should be getting a garbage output. – Rafed Nole Nov 30 '13 at 13:20
  • More detailed discussion of `a^a` [here](http://stackoverflow.com/questions/25074180/is-aa-or-a-a-undefined-behaviour-if-a-is-not-initialized/) – M.M Feb 16 '15 at 23:40

4 Answers4

10
int a;
printf("%d",(3^6)+(a^a));

The evaluation of the (3^6)+(a^a) expresion invokes undefined behavior as a is not initialized and has an indeterminate value.

(C11, 6.3.2.1p2) "If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined."

ouah
  • 142,963
  • 15
  • 272
  • 331
  • It doesn't matter, because the expression a^a always yields 0, no matter what value it has. – datenwolf Nov 30 '13 at 13:15
  • 10
    @datenwolf it DOES matter. C says it invokes undefined behavior. – ouah Nov 30 '13 at 13:16
  • 6
    @datenwolf UB permits that, for example, `a` appears to be 1 when first read, then its value suddenly changes to 0. Then `a ^ a` would **not** be 0. UB is UB, and there are no implications/constraints for the output of a program with undefined behavior. –  Nov 30 '13 at 13:17
  • @H2CO3: That kind of behavior for `a` was only permitted if it was declared with the `volatile` storage qualifier. Without being declared `volatile` the standard explicitly says that any changes to the values of a variable are permitted only through statements of the program itself. But there are no value altering statements inbetween. – datenwolf Nov 30 '13 at 13:23
  • 5
    @datenwold where did you read in 6.3.2.1p2 the `volatile` qualifier is required? The behavior being undefined `a ^ a` could evaluate to `42`, or the program can crash, etc. – ouah Nov 30 '13 at 13:25
  • 5
    @datenwolf But, since the program has UB (because it reads an uninitialized variable), it can do literally anything; UB doesn't mean that "this one value will be indeterminate but every other statement must behave as normal". UB rather means that "the only rule is that there's no rule". So **any** behavior/output can be expected from such a program. It is not conforming, and thus it need not obey to the rules the standard enforces for **correct, conforming** programs. –  Nov 30 '13 at 13:26
  • 1
    @H2CO3: C language lawyers are always so quick to jump on the UB wagon, without realizing what it actually means. In the case of OP question it means that the result of reading a value of uninitialized `a` yields a undefined result. Undefined can also mean, that the implementation itself adds some special definition to it (it's perfectly valid for a certain C implementation to fill the undefined parts with custom definitions). This allowance also means, that all the other rules of the standard further applied. You can't say "Oh doing this invokes UB, hence I can stop thinking here". – datenwolf Nov 30 '13 at 13:26
  • 9
    @datenwolf "You can't say "Oh doing this invokes UB, hence I can stop thinking here"" - oh yes, we can. That's *exactly* the point of UB. Also, you are confusing undefined **behavior** and unspecified **values.** The two are not equivalent. –  Nov 30 '13 at 13:27
  • 5
    @datenwolf Yes you can, that's the definition of UB. You might be thinking of "unspecified behaviour", which the compiler is required to document (and it isn't portable, and since we don't know the OP's compiler it is still undefined to us). – Thomas Nov 30 '13 at 13:28
  • 1
    @Thomas: Well, your argument actually plays to mine: A compiler could define that in it's own implementation all not explicitily initialized variables are set to zero. Then within that implementation you have some implementation defined bahavior. If you overlay that with the rest of the C standard, `a^a` becomes an invariant. But `a^a` is always invariant, it's a constant expression no matter what value `a` does have. – datenwolf Nov 30 '13 at 13:30
  • 3
    @datenwolf: There's always going to be someone who'll start endless discussions about how some kind of undefined behaviour can be made a little less undefined by some kind of black magic du jour. It's the equivalent of a scientific research programme into the colour of the invisible unicorn - but at some point you just have to stand up to the fact that it's invisible. – Kerrek SB Nov 30 '13 at 13:31
  • 5
    @datenwolf Thomas was talking about **unspecified** behavior, and not **undefined** behavior. –  Nov 30 '13 at 13:31
  • @ouah: Okay, where in 6.3.2.1 can I find that the read of a variable between statement may change, if no explicit change is made? I don't see it. – datenwolf Nov 30 '13 at 13:32
  • 4
    @datenwolf It's here: "*the behaviour is undefined*" – Thomas Nov 30 '13 at 13:33
  • 5
    @datenwolf It's implicit. The definition of UB in C99, 3.4.3.1 is that "behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements". So it isn't a requirement that the variable retain its value if the program has UB. –  Nov 30 '13 at 13:34
  • 7
    @datenwold welcome to the realm of undefined behavior – ouah Nov 30 '13 at 13:35
  • @ouah: Any compiler developers here? If so, I'd like to see how difficult it is to tweak their AST optimizers to recognize that 1) `a` is uninitialized and to ignore that 2) the optimizer figures out that `a^a` is a constant expression that should get evaluated at compile time as of 6.6 – datenwolf Nov 30 '13 at 13:52
  • 5
    @datenwolf Yes, **most** implementations will indeed evaluate it to zero. But can anyone rely on it? No. Your code can stop working at a mere change of compiler flags or because today is raining. – Guilherme Bernal Nov 30 '13 at 13:59
  • @GuilhermeBernal: This is almost like arguments between physicists and mathematicians :) – Being a physicist I prefer a more practical approach on this; in addition to the logic of pure math we also have the constraints of the laws of nature there. And just like that, there's a certain way (theoretical) computers work that determines how programs should be interpreted. – datenwolf Nov 30 '13 at 14:04
  • @GuilhermeBernal: The value of `a` gets read only in the expression `a^a`. But the result of that it known it advance: A is an integer and the standard is very specific about how integers are to be treated: They have a certain size and a very strict and limited set of values they take on (a rather small set if I may comment on that). We may add an additional "undefined" value to that set, that we can never assign, but which the integer can take on. – datenwolf Nov 30 '13 at 14:06
  • @GuilhermeBernal: Which would mean that there's one specific "value" for which the rules of integers get broken, but the standard doesn't provision for that. The behavior of integers is well defined for all values within their set of attainable values. By making a call on "UB" you're actually introducing an inconsistency on the whole thing. By saying "oh this invokes UB" you're technically opening a huge can of worms on the whole standard if you really want to get technical, and assume that "undefined" is just another state (i.e. value) `a` can take on. Just my 2 cents. – datenwolf Nov 30 '13 at 14:09
  • 2
    @datenwolf, you are assuming that the expression `a` reads the value of the variable. But the standard only says that it reads the value when the variable is initialized. Maybe the expression `a` prints "Hello World" on the screen and quits when it is not, who knows? – Guilherme Bernal Nov 30 '13 at 14:10
  • Oh, and I'd like to point to/ask about 6.6p8 (arithmetic constant expressions). Isn't `a^a` exactly that? EDIT: What I mean is, that you don't need to read the value of `a` at all to evaluate that expression. So no read at all is required for that program, which according to your logic could be interpreted as, that no read from the variable itself is required. – datenwolf Nov 30 '13 at 14:11
  • 1
    C11, 6.6p8: "An arithmetic constant expression shall have arithmetic type and shall only have operands that are integer constants, floating constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and _Alignof expressions. Cast operators in an arithmetic constant expression shall only convert arithmetic types to arithmetic types, except as part of an operand to a sizeof or _Alignof operator." I don't see how it relates. `a` is not a integer constant or anything mentioned here. – Guilherme Bernal Nov 30 '13 at 14:15
  • @GuilhermeBernal: Well, that leaves the question if `a^a` is constant or not. Most C optimizers will eliminate any code that yields a constant value; of course this optimization must be based on the C standard then, to be allowed. So the question that remains is: *If an expression can be eliminated symbolically and within the rules of the language standard, does it then still yield a read?* – datenwolf Nov 30 '13 at 14:24
  • 6
    @datenwolf The standard is not concerned with a read in the resulting assembly or whatever. It is concerned with operations of the abstract machine. Of course, due to the "as-if" rule, a compiler is permitted to eliminate `a ^ a` (if the behavior of the program is defined), but the C abstract machine still does **every step exactly as described in the source code,** so yes, `a ^ a` **always** results in two reads; perhaps not physically or at the actual assembler level, but theoretically. And that in itself is undefined behavior. Nobody cares if `a ^ a` will be optimized to constant 0 or not. –  Nov 30 '13 at 14:44
  • "that leaves the question if a^a is constant or not" -- Not if you can read plain English. None of the operands of a^a are constants, sizeof expressions, or _Alignof expressions. – Jim Balter Aug 01 '14 at 09:29
  • "a^a is always invariant, it's a constant expression no matter what value a does have" -- C isn't math so, no. – Jim Balter Aug 01 '14 at 09:32
  • "here's a certain way (theoretical) computers work that determines how programs should be interpreted" -- This isn't about how computers work, it's about how compilers work. – Jim Balter Aug 01 '14 at 09:35
6

I am getting confused as to what this ^ sign is doing in a C program.

^ is a logical XOR operator (do not confused with power operator, unfortunately not available in C).

Output of the expression (3^6)+(a^a) in C language?

The output of the program is garbage value because your program's behavior is undefined. Why? Because a is not initialized.

n1570: Annex J: J.2 Undefined behavior

The behavior is undefined in the following circumstances:
...
— An lvalue designating an object of automatic storage duration that could have been declared with the register storage class is used in a context that requires the value of the designated object, but the object is uninitialized (6.3.2.1).1


1. Emphasis is mine.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
  • 3
    @Kninnug I'm guessing because `a` is never initialized. – luiscubal Nov 30 '13 at 13:15
  • 5
    +1 this is the right answer. Reading an uninitialized variable results in UB. –  Nov 30 '13 at 13:16
  • 4
    @datenwolf; If standard says it is undefined then it is undefined and that's it. – haccks Nov 30 '13 at 13:17
  • "The output of the program is garbage value" -- There is no such thing as a "garbage value". The results are simply undefined by the standard, but almost every implementation will produce the value 2. – Jim Balter Aug 01 '14 at 09:33
5

The output of the program would result in undefined behavior as a is not initialized and hence the output will result in any garbage value.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
1

^ stands for XOR.

XORing same bit return 0, different bit return 1.

Eg. 1^0 == 1 , 1^1 == 0

Any int variable in C is 16 bit (16 bit compiler) or 32 bit (32 bit compiler). So, in any case whether it is defined or not, a will be a 16/32 bit pattern.

Considering 16 bit compiler

Bit pattern of 3 is 0000 0000 0000 0000 0011

XOR

Bit pattern of 6 is 0000 0000 0000 0000 0110

Result is --> 0000 0000 0000 0000 0101 ---> 5

It doesn't matter whether a is defined or not.

a^a will always be equal to 0. Since we have bit pattern same in both cases.

Therefore (3^6) + (a^a) = 5.


Also if question is (3^6) + (a^~a)

Then as explained above 3^6--> 5

Considering 16 bit compiler for a as garbage value and integer type let assume a=1. then a will be 0000 0000 0000 0001

and ~a will be 1111 1111 1111 1110

so a^~a will be -->1111 1111 1111 1111--> 65535 (Unsigned int)

Therefore (3^6) + (a^~a) = 5+65535 =65540 which is out of range.

As a result it will exceed 5 starting from 0 which will result -->4

Answer=4