是否有 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 中的定义兼容。