是否有 gcc 编译器选项可帮助捕获形式参数和实际参数类型不匹配?
Is there a gcc compiler option that help capture formal and actual parameter type mismatch?
//file1.c
#include <stdio.h>
void p(int a)
{
printf("%d\n",a);
}
//file2.c
extern void p(float x); // external declaration doesn't match definition
int main(){
float b;
b=3.333f;
p(b);
}
这里的外部声明是错误的,它与实际的函数定义不同。我编译并 link 这两个文件:
gcc -Wconversion -Wall -std=c99 file1.c file2.c
没有发出警告。是否有任何 gcc 编译器选项可以帮助捕获 compiling/linking 期间的这种不匹配?
此代码导致未定义的行为,因为函数是通过与函数定义不兼容的声明调用的。
为此,您可以:
- 使用
-flto
将在 link 时间执行原型检查
- 使用
-Wmissing-declarations
将警告 file1
具有外部 linkage 但没有原型的函数
- 养成从不在
.c
文件中手动编写 extern
函数声明的习惯 -- 始终包含一个 .h
文件,该文件也包含在 .c
包含函数定义的文件(前一个选项将对此发出警告)。
编译器在编译 file2.c 时不可能观察到其中的声明与 file1.c 中的声明不匹配,因为在编译 file2.c 时,编译器不知道 file1.c.
的内容
一些链接器具有可以帮助解决此问题的功能。但是,这不是链接 C objects 的常见做法。 (也许它应该是。)
这种不匹配通常使用 header 文件来处理。压倒性的常见做法是包含来自 header 的声明,而不是在其他源文件中手动输入它们。为此:
- 创建 file1.h 并在其中放入
void p(int a);
。
- 在file1.c中插入
#include "file1.h"
.
- 在file2.c中插入
#include "file1.h"
并删除p
的声明。
在file1.c中包含[=36=]的目的是让编译器看到file1.h中的声明和file1.c中的定义,它会报错如果它们不兼容。
那么,由于 file1.h 包含在 file2.c 中,我们可以确信编译 file2.c 时看到的声明与 file1.c 中的定义兼容。
//file1.c
#include <stdio.h>
void p(int a)
{
printf("%d\n",a);
}
//file2.c
extern void p(float x); // external declaration doesn't match definition
int main(){
float b;
b=3.333f;
p(b);
}
这里的外部声明是错误的,它与实际的函数定义不同。我编译并 link 这两个文件:
gcc -Wconversion -Wall -std=c99 file1.c file2.c
没有发出警告。是否有任何 gcc 编译器选项可以帮助捕获 compiling/linking 期间的这种不匹配?
此代码导致未定义的行为,因为函数是通过与函数定义不兼容的声明调用的。
为此,您可以:
- 使用
-flto
将在 link 时间执行原型检查 - 使用
-Wmissing-declarations
将警告file1
具有外部 linkage 但没有原型的函数 - 养成从不在
.c
文件中手动编写extern
函数声明的习惯 -- 始终包含一个.h
文件,该文件也包含在.c
包含函数定义的文件(前一个选项将对此发出警告)。
编译器在编译 file2.c 时不可能观察到其中的声明与 file1.c 中的声明不匹配,因为在编译 file2.c 时,编译器不知道 file1.c.
的内容一些链接器具有可以帮助解决此问题的功能。但是,这不是链接 C objects 的常见做法。 (也许它应该是。)
这种不匹配通常使用 header 文件来处理。压倒性的常见做法是包含来自 header 的声明,而不是在其他源文件中手动输入它们。为此:
- 创建 file1.h 并在其中放入
void p(int a);
。 - 在file1.c中插入
#include "file1.h"
. - 在file2.c中插入
#include "file1.h"
并删除p
的声明。
在file1.c中包含[=36=]的目的是让编译器看到file1.h中的声明和file1.c中的定义,它会报错如果它们不兼容。
那么,由于 file1.h 包含在 file2.c 中,我们可以确信编译 file2.c 时看到的声明与 file1.c 中的定义兼容。