Riddle me this

Found this today while playing around, thought people might enjoy this riddle.

$> echo test.c
typedef int foo;
int main()
  foo foo = 1;
  return (foo) +0;
$> gcc -Wall -o test test.c && ./test && echo $?

What does this print?

  1. 0
  2. 1
  3. Some compilation warnings, then 0.
  4. Some compilation warnings, then 1.
  5. It doesn’t compile.

I’ll put an answer in the comments.


#1 Benjamin Otte on 10.17.19 at 22:56

The answer is (2) – it successfully compiles and then returns 1.

The reason is that the local definition of foo shadows the global typedef once it is declared, so (foo) evaluates to (1) and not to an (int) cast.
Compiling with -Wshadow (which is not included in -Wall) would cause a warning about shadowing.
Moving the declaration of the variable out of main() and into the global scope would cause compilation to fail.

#2 Lars on 10.18.19 at 06:01

I think you meant “cat test.c”, not “echo test.c”

#3 antoniof on 10.18.19 at 08:14

`+0` gave it away for me.

`return (foo) -1;` might better fool readers.

#4 Black_Fox on 10.18.19 at 08:29

Since ./test returns 1, the && doesn’t happen and nothing is printed :-)

#5 Sam Thursfield on 10.18.19 at 19:09

I guessed (3) — but no!

#6 Cornel Panceac on 10.20.19 at 04:42

Actually for me it does not print anything. This is probably because ./test ends with exit code ‘1’.

Changing the line like this, prints ‘1’:
$ gcc -Wall -o test test.c && ./test ; echo $?

I confirm -W shadow behaviour.

#7 Ingmar on 10.21.19 at 15:19

6) It doesn’t print anything.

As && only executes the right-hand command after successful execution of the left-hand command and ./test exits with exit code 1, echo $? will not be executed ;-)

#8 Herb on 10.21.19 at 23:51

The answer is None of the above. It doesn’t print anything at all. The exit code of ./test is non-zero, so because of the && following it the echo command doesn’t get executed.