2
#include<stdio.h>

int main()
{
    printf("%d",printf("%d %d",2,2) & printf("%d %d",2,2));
}

The output comes like this: 2 2 2 2 3

I cannot figure out why the output is like this. Any ideas?

BryanH
  • 5,826
  • 3
  • 34
  • 47
user507401
  • 2,809
  • 9
  • 25
  • 20

1 Answers1

15

printf returns the numbers of characters printed, so here is the explanation:

printf("%d",printf("%d %d",2,2) & printf("%d %d",2,2));
\_________/ \_________________/ | \_________________/
     |              |           |          |
     |         prints "2 2"     |    prints "2 2"
     |         and returns 3    |    and returns 3
     |                          |
     |                    computes 3 & 3
     |                   (which equals 3)
     |
 prints "3"
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • +1 for noting why the return values from `printf` are what they are. – Karl Knechtel Jan 30 '11 at 09:40
  • 1
    Note that the order of the evaluation of the two `printf("%d %d", 2, 2)` expressions isn't defined by the standard, but they print the same thing either way, so I don't know whether it's undefined behavior or not. – Chris Lutz Jan 30 '11 at 09:42
  • @Chris: Why would it be undefined behavior? – GManNickG Jan 30 '11 at 09:43
  • @GMan - If the order of evaluation of the arguments of `&` is undefined then the order the side effects happen is undefined. I think? (Or is it just the order of evaluation of function arguments that is undefined?) – Chris Lutz Jan 30 '11 at 09:45
  • @GMan: http://stackoverflow.com/questions/376278/parameter-evaluation-order-before-a-function-calling-in-c/395991#395991 – sarnold Jan 30 '11 at 09:49
  • 1
    @Chris: The order arguments to a function are evaluated is unspecified. Operators, though, have *associativity*, and are evaluated either left-to-right, or right-to-left. The `&` (bitwise-and) operator evaluates left-to-right, so the left-hand `printf` gets evaluated first (called first). – GManNickG Jan 30 '11 at 09:52
  • 1
    @sarnold: I know, but the bitwise-and operator is not a function. – GManNickG Jan 30 '11 at 09:52
  • 3
    @GMan - 6.5, paragraph 3: "The grouping of operators and operands is indicated by the syntax. Except as specified later (for the function-call(), &&, ||, ?:, and comma operators), the order of evaluation of subexpressions and the order in which side effects takeplace are both unspecified." – Chris Lutz Jan 30 '11 at 09:58
  • And 6.5.13 (about logical `&&`) specifically mentions the difference between `&&` (which guarantees evaluation order) and `&` (which doesn't): "Unlike the bitwise binary `&` operator, the `&&` operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares equal to 0, the second operand is not evaluated" – Chris Lutz Jan 30 '11 at 10:00
  • @Chris: Ah, look at that. I thought it was functions only. I revoke my previous statement, though I still don't see where UB enters. – GManNickG Jan 30 '11 at 10:01
  • @GMan - It's unspecified, which is also bad but doesn't affect this example since both inner `printf` calls produce the same result regardless. – Chris Lutz Jan 30 '11 at 10:05
  • @Chris: Right, but if they didn't that shouldn't change anything. It just isn't specified which text appears first. – GManNickG Jan 30 '11 at 10:18
  • @GMan - At this point we're just vehemently agreeing with each other. When I started this I thought it was undefined (instead of unspecified) behavior, and thus that the compiler would be allowed to do anything with the code. – Chris Lutz Jan 30 '11 at 10:23