gpt4 book ai didi

c - IOCCC 1984/decot.c - 可以在 21 世纪编译吗?

转载 作者:行者123 更新时间:2023-12-03 17:04:12 27 4
gpt4 key购买 nike

这段引人入胜的代码出现在第一届(1984 年)国际混淆 C 代码竞赛中:
http://www.ioccc.org/years.html#1984 (装饰)
在清除了由 goto 和一些偷偷摸摸的注释引起的预处理器滥用和未使用代码的碎片之后,您最终得到了以下幸存代码(如果我错了,请纠正我!):

#include <stdio.h> //used to suppress warnings
#include <math.h> //used to suppress warnings
extern int fl00r; //renamed to not clash with floor from math.h - unless it's part of the trickery???
int b, k['a'] = {
sizeof(int(*)()),
};
struct tag {int x0,*xO;}

*main(int i, int dup, int signal) { //int added to suppress warnings
for(signal=0;*k *= * __FILE__ *i;) {
printf(&*"'\",=); /*\n\\", (*((int(*)())&fl00r))(i)); //see line 3
if(b&&k+sin(signal)/ * ((main) (b)-> xO));
}
}
有一个编译器错误需要克服:
decot.c: In function 'main':
decot.c:12:28: error: too few arguments to function 'main'
12 | if(b&&k+sin(signal)/ * ((main) (b)-> xO));
| ^
decot.c:9:2: note: declared here
9 | *main(int i, int dup, int signal) {
| ^~~~
我怀疑编译器在当时的工作方式意味着您可以以某种方式仅使用 1 个参数调用 main,即使在这种情况下它是用 3 专门定义的。
这是准确的吗?我错过了什么吗?如今,使此代码能够编译所需的最少更改是什么?
我在 Makefile 中使用了 GCC 9.2.0 和建议的构建命令。
如果我错过了一些非常明显的东西,请提前致谢并道歉!

最佳答案

tl;博士; 您的错误是将 ANSI C 原型(prototype)提供给 main 函数(即将 i 更改为 int i 等),这指示编译器检查其被调用的参数并导致 too few arguments 错误。
例子:

echo 'int foo(a,b){return a+b;} int main(){return foo(3);}' |
cc -Wall -std=c89 -xc -
# K&R C function OK, no errors

echo 'int foo(int a, int b){return a+b;} int main(){return foo(3);}' |
cc -Wall -std=c89 -xc -
...
<stdin>:1:54: error: too few arguments to function ‘foo’

该代码应该使用传统的 C 预处理器进行预处理,而不是使用“ANSI C”预处理器。使用标准预处理器会产生一些伪像,例如 << = 代替 <<=* = 代替 *= 等。
cpp -traditional-cpp -P decot.c > decot1.c
在添加正确的函数声明并添加强制转换之后——请参阅此答案末尾的差异和结果——您会得到在 c89 中编译时带有单个警告的内容(以及在 c99 中的几个),并且 as described ,将一些垃圾打印到标准输出:
$ cc -std=c89 decot1.c -lm -o decot1
decot1.c: In function ‘main’:
decot1.c:13:33: warning: function called through a non-compatible type
(printf(&*"'\",x); /*\n\\", (*((int(*)())&floor))(i)));
~^~~~~~~~~~~~~~~~~~~~
$ ./decot1
'",x); /*
\
这与我在 V7 Unix 上编译和运行原始版本时得到的完全相同,所以它应该是正确的 ;-)
decot1.c
double floor(double);
double sin(double);
int printf(const char*, ...);
int b,
k['a'] = {sizeof(
int(*)())
,};
struct tag{int x0,*xO;}

*main(i, dup, signal) {
{
for(signal=0;*k *= * "decot.c" *i;) do {
(printf(&*"'\",x); /*\n\\", (*((int(*)())&floor))(i)));
goto _0;

_O: while (!(k['a'] <<= - dup)) {
static struct tag u ={4};
}
}


while(b = 3, i); {
k['a'] = b,i;
_0:if(b&&k+
(int)(sin(signal) / * ((main) (b)-> xO)));}}}
差异
$ diff -u decot1.c~ decot1.c
--- decot1.c~
+++ decot1.c
@@ -1,4 +1,6 @@
-extern int floor;
+double floor(double);
+double sin(double);
+int printf(const char*, ...);
int b,
k['a'] = {sizeof(
int(*)())
@@ -20,4 +22,4 @@
while(b = 3, i); {
k['a'] = b,i;
_0:if(b&&k+
- sin(signal) / * ((main) (b)-> xO));}}}
+ (int)(sin(signal) / * ((main) (b)-> xO)));}}}

关于c - IOCCC 1984/decot.c - 可以在 21 世纪编译吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64146354/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com