Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 荒诞的汇编_C - Fatal编程技术网

C 荒诞的汇编

C 荒诞的汇编,c,C,这是一个基本的C代码,我认为它应该抛出三个错误(函数未定义、函数未返回任何内容、函数参数丢失)。但令我惊讶的是,它没有抛出任何东西,它编译并给出了一些垃圾结果: #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int a=f1(); printf("a %d\n",a); system("PAUSE"); return 0; }

这是一个基本的C代码,我认为它应该抛出三个错误(函数未定义、函数未返回任何内容、函数参数丢失)。但令我惊讶的是,它没有抛出任何东西,它编译并给出了一些垃圾结果:

#include <stdio.h>

#include <stdlib.h>

int main(int argc, char *argv[])
{
    int a=f1();
    printf("a %d\n",a);
    system("PAUSE");    
    return 0;
}


f1(int *t)
{
       printf("t %d", t);
}
#包括
#包括
int main(int argc,char*argv[])
{
int a=f1();
printf(“a%d\n”,a);
系统(“暂停”);
返回0;
}
f1(整数*t)
{
printf(“t%d”,t);
}

PS:我在windows上使用gcc编译器。

在C中,当函数未声明时,假定返回
int
,编译继续(顺便说一句)。如果函数声明时没有类型(如代码中的
f1()
),则假定返回
int
。不从非void函数(如代码中)返回值是未定义的行为


因此,您提到的任何一点都不需要导致编译错误。不需要使用未定义的行为来阻止程序运行-程序可能会运行,甚至可能会产生好看的结果。

尝试使用
-Wall
标志再次编译。这样会打开所有警告,然后您将看到大量警告:

c.c: In function ‘main’:
c.c:7: warning: implicit declaration of function ‘f1’
c.c: At top level:
c.c:15: warning: return type defaults to ‘int’
c.c: In function ‘f1’:
c.c:16: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’
c.c:17: warning: control reaches end of non-void function

由于您没有任何编译时错误,只有警告,因此代码编译得很好。它执行得不太好。

首先,您没有在启用警告的情况下编译。您通常至少应该使用
-Wall
开关调用gcc-对于示例代码,它给出:

x.c: In function 'main':
x.c:7: warning: implicit declaration of function 'f1'
x.c: At top level:
x.c:15: warning: return type defaults to 'int'
x.c: In function 'f1':
x.c:16: warning: format '%d' expects type 'int', but argument 2 has type 'int *'
x.c:17: warning: control reaches end of non-void function

其次,它编译的原因是它中的所有错误都是一种称为“未定义行为”的形式,这意味着编译器不需要诊断它们并停止编译-它只会产生垃圾结果。

如果使用gcc的
-Wall
选项启用所有警告,您可能会更高兴。然后在编译时您会看到:

C:\test>make
gcc -Wall prog.c -o prog
prog.c: In function 'main':
prog.c:7:5: warning: implicit declaration of function 'f1'
prog.c: At top level:
prog.c:14:1: warning: return type defaults to 'int'
prog.c: In function 'f1':
prog.c:16:8: warning: format '%d' expects type 'int', but argument 2 has type 'int *'
prog.c:17:1: warning: control reaches end of non-void function

您还可以使用
-Werror
将所有警告转化为错误(因此您必须修复它们).

如果您将
-Wall
添加到gcc命令中,您应该会收到一些警告。我猜它的工作原理与旧式C具有松散的函数原型一样。并且将假定未知函数返回
int
。链接器工作是因为没有未定义的符号(
f1
存在),但堆栈上传递的是垃圾(即无)不是预期的。

f1被认为具有隐式原型“int f1(int)”。 因此,该调用是有效的。 f1不返回任何内容,但隐式支持它返回int:行为未定义。 编译器可能会警告您隐式原型与定义不一致。它还可能要求正确的返回。这是编译器内部静态分析可能执行的检查的一部分:gcc不执行此操作,其他人可能执行此操作。
在任何情况下,编译器通常不会保证任何不符合ISO标准的程序。

我知道,默认情况下,它的返回类型是int。但问题是,如果我没有明确提到它,编译器是否会自己添加返回语句?…当我在calli之前没有声明它时,它是如何选择函数的定义的是否调用函数?@Nik:你不能指望添加
return
——行为是未定义的。在C语言中,你可以在函数声明之前调用它——它被假定为返回
int
。你所说的一切都是有意义的,但是参数不匹配怎么办?@Nik:假定没有参数——被调用的函数很可能会得到它的actu根据调用约定调用参数-一些垃圾,它需要一个参数。