这是一名大一学生写的代码。我正在检查他的代码是错还是正确。我发现了一个错误的观点。它是由参数和参数的类型不匹配引起的。
void make_data(FILE *fp,char,int n);
这是一个函数的原型。然而,他用不同的论点称这个函数。像这样。
make_data(fin, "input.txt", 10);
错误的观点显而易见 - 他以错误的方式宣布了函数原型。我首先使用cl.exe(64位)编译此代码并执行该程序。它在运行时停止了。
但是,当我使用cl.exe(32位)编译同一文件时,它不会发生运行时错误。当然有很多编译警告,但至少它执行得很好。似乎cl.exe(32位)比64位更宽容。但它们的版本相同。(16.00.30319.01)。那他们为什么表现得不同呢?
我知道这是一种未定义的行为。我知道Visual C编译器可能与gcc非常不同 - 因为C语言没有定义所有细节。我想知道的是为什么32位系统和64位系统中的编译器应该是这样的。
答案 0 :(得分:1)
您显示的代码是有效的C.它是无意义的,但就C语义而言,它是有效的并且不会调用UB。
完整示例:
#include <stdio.h>
void make_data(FILE *fp, char a, int n) {
printf("%p %c %d\n", fp, a, n);
}
int main()
{
FILE * fin = NULL;
make_data(fin, "input.txt", 10);
}
示例输出:
0x0 2 10
您没有告诉我们的是,不同翻译单位的声明是不同的。例如。在file1.c
中,有一个void make_data(FILE*, char, int);
声明,而在file2.c
中有一个void make_data(FILE*, char*, int) { ... }
定义。在64位系统上,char
和char*
以不同的方式传递,这会导致崩溃。
因此,重申一下,问题在于您没有正确识别问题 - 尽管如果您只是遵循指示,它是完全可以预防的。请阅读并理解how to ask a good question page。 在提交问题之前,只有最小化问题并且能够重现它才会出现在您身上。