【问题标题】:IOCCC 1988/isaak.c - why no output even after ANSIfication?IOCCC 1988/isaak.c - 为什么即使在 ANSI 化之后也没有输出?
【发布时间】:2021-01-25 20:52:59
【问题描述】:

从 1988 年开始,IOCCC 获奖作品中精心设计的自包含代码:

http://www.ioccc.org/years.html#1988_isaak

...当时对于某些系统来说还是太多了。此外,ANSI C 终于成为混乱的 K&R 生态系统的稳定替代品。因此,IOCCC 评委也提供了这个条目的 ANSI 版本:

http://www.ioccc.org/1988/isaak.ansi.c

它的主要吸引力在于它在最后一行(!)中包含<stdio.h> 和经过深思熟虑的#defines 的噱头,无论是在源代码内部还是在编译时,都只允许代码的某些部分进入正确的水平。这就是允许 <stdio.h> 标头最终包含在可能的最新阶段的原因,就在必要之前,在提供给编译器的源代码中。

但是,今天使用提供的编译器设置编译时,此版本仍然无法生成输出:

gcc -std=c89 -DI=B -DO=- -Dy isaak.ansi.c
tcc -DI=B -DO=- -Dy isaak.ansi.c

使用的版本:GCC 9.3.0、TCC 0.9.27

对编译后的二进制文件名没有任何明显的依赖,因此我将其留给编译器选择。即使使用-o isaak-o isaak.ansi,也会出现相同的结果:没有输出。

这是什么原因造成的?输出功能如何失败?可以做些什么来纠正这个问题?

提前致谢!

注意:IOCCC 评委意识到此条目存在可移植性问题,会降低其混淆价值,因此决定还包括代码输出的 UUENCODE 版本:

http://www.ioccc.org/1988/isaak.encode

【问题讨论】:

    标签: c gcc obfuscation ansi-c tcc


    【解决方案1】:

    这个程序没有任何远程可移植性。正如我所见,它试图用自己的代码覆盖exit 标准库函数,期望从空的main() 返回会调用that exit(),这是不正确的。即便如此,这种行为也不符合标准——甚至 C89 也表示它会有未定义的行为。

    您可以通过在 main 中实际调用 exit(); 来“修复”现代 GCC / Linux 上的程序 - 只需将第一行更改为

    main(){exit(0);}
    

    我编译了gcc -std=c89 -DI=B -DO=- -Dy isaak.ansi.c 并运行./a.out 并得到了合理的输出。

    【讨论】:

      猜你喜欢
      • 2021-01-04
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 2012-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多