Question

OK, I will bite. An answer to the massively popular Why does the C preprocessor interpret the word "linux" as the constant "1"? question mentions that

main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}`

prints "unix", but for reasons that have absolutely nothing to do with the spelling of the macro name.

I read http://www.ioccc.org/1987/korn.hint but I think quite more detail would help unobfuscating this :)

Was it helpful?

Solution

unix is 1 because of an implicit #define in the compiler or the runtime environment.

Thus, and because a[b] == b[a] == *(a + b) and thus 1["xy"] == "xy"[1], you get:

  • &unix["\021%six\012\0"] points to "%six\012\0"
  • (unix)["have"] = "have"[1] = 'a',
  • "'a'+"fun"-0x60" = "fun" + 1 = "un".

This leads you to printf("%six\012\0", "un"); which clearly does print "unix\012", \012 being a line break (the same as \n).

If unix is undefined, e. g. on a Windows system, you get an error.

If unix was 0 (can that ever be the way on a clean system?), you get

printf("\012%six\n", 'h'+"fun"-0x60)

where the 2nd argument is "fun"+8, pointing to Nirvana and leading to undefined behaviour.

OTHER TIPS

Normally I think it should print "unix" only when compiled under a unix-like system.

That's because on such systems, unix is a predefined macro with a value of 1.

As such, it translates as:

main() { printf(&1["\021%six\012\0"], (1)["have"]+"fun"-0x60); }

Re-ordered to dispose of the int[array] nonsense, we get:

main() { printf(&"\021%six\012\0"[1], "have"[1] + "fun"-0x60); }

We can ignore the \021 since it's skipped (I'll just replace it with a ?), and translate the \012 into \n:

main() { printf(&"?%six\n\0"[1], 'a' + "fun" - 0x60); }
main() { printf(  "%six\n",     0x61 + "fun" - 0x60); }

Which gives:

main() { printf("%six\n", "un"); }

Note: I was re-solving it as I went (especially the second part), but the first time I saw it I needed two hints to even understand the explanation:

  • unix means 1
  • int[array] is an actual notation that the compiler accepts.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top