Why does the 1987 Korn oneliner print unix?
好的,我会咬人的。 大众流行的答案为什么C预处理器将单词"linux"解释为常量"1"? 问题提到
1
| 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.
我阅读http://www.ioccc.org/1987/korn.hint,但我认为更多的细节将有助于不混淆这:)
-
这个"问题"提出了一个难题,而不是一个问题。
-
@EricPostpischil现在一个谜题可能会困扰人们,如果人们感到困惑,他们往往会提问。
由于编译器或运行时环境中存在隐式#define,因此unix为1。
因此,因为a[b] == b[a] == *(a + b)因此1["xy"] =="xy"[1],你得到:
-
&unix["\021%six\012\0"]指向"%six\012\0"
-
(unix)["have"] ="have"[1] = 'a'
-
"'a'+"fun"-0x60" ="fun" + 1 ="un"。
这将导致printf("%six\012\0","un");显然打印"unix\012",\012是换行符(与
相同)。
如果unix未定义,e。 G。在Windows系统上,您收到错误。
如果unix 0(这可能是一个干净的系统吗?),你得到
1 2
| printf("\012%six
", 'h'+"fun"-0x60) |
其中第二个参数是"fun"+8,指向Nirvana并导致未定义的行为。
通常我认为它应该只在unix类系统下编译时打印"unix"。
这是因为在这样的系统上,unix是一个预定义的宏,其值为1。
因此,它翻译为:
1
| main () { printf(&1["\021%six\012\0"], (1)["have"]+"fun"-0x60); } |
重新命令处置int[array]废话,我们得到:
1
| main () { printf(&"\021%six\012\0"[1],"have"[1] +"fun"-0x60); } |
我们可以忽略\021,因为它被跳过(我只是用?替换它),并将\012转换为
:
1 2 3 4
| main () { printf(&"?%six
\0"[1], 'a' +"fun" - 0x60); }
main () { printf( "%six
", 0x61 +"fun" - 0x60); } |
这使:
1 2
| main () { printf("%six
","un"); } |
注意:我一直在重新解决它(特别是第二部分),但是第一次看到它时我需要两个提示才能理解解释:
-
unix表示1
-
int[array]是编译器接受的实际表示法。