作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这段引人入胜的代码出现在第一届(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 专门定义的。
最佳答案
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’
<< =
代替
<<=
,
* =
代替
*=
等。
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 上编译和运行原始版本时得到的完全相同,所以它应该是正确的 ;-)
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/
这个问题在这里已经有了答案: 1998 vintage C code now fails to compile under gcc (2 个回答) 1年前关闭。 来自 1987 年 IOCCC 的这条
1988 年 IOCCC 获奖作品中精心制作的自包含代码: http://www.ioccc.org/years.html#1988_isaak ...对于当时的某些系统来说仍然太多了。此外,ANSI
这段引人入胜的代码出现在第一届(1984 年)国际混淆 C 代码竞赛中: http://www.ioccc.org/years.html#1984 (装饰) 在清除了由 goto 和一些偷偷摸摸的注释
我是一名优秀的程序员,十分优秀!