Gcc 警告风险

Gcc 警告风险,gcc,armcc,Gcc,Armcc,我主要有两种编译警告: 1。隐式函数声明 在a.c中,它有char*foo(char*ptr1,char*ptr2),在b.c中,一些函数使用这个foo函数而没有任何声明,我发现编译器似乎会将函数foo返回值视为整数,甚至我也可以传递一些小于或大于foo函数声明的变量 2。枚举类型与其他类型混合 我的目标芯片是ARM11,似乎即使我没有解决这两种编译警告,我的程序也可以运行,没有任何问题,但我相信这背后一定有一些风险。有谁能给我举个好例子,说明这两种编译警告会导致一些意想不到的问题 同时,若这两

我主要有两种编译警告:

1。隐式函数声明

a.c
中,它有
char*foo(char*ptr1,char*ptr2)
,在
b.c
中,一些函数使用这个
foo
函数而没有任何声明,我发现编译器似乎会将函数
foo
返回值视为整数,甚至我也可以传递一些小于或大于
foo
函数声明的变量

2。枚举类型与其他类型混合

我的目标芯片是ARM11,似乎即使我没有解决这两种编译警告,我的程序也可以运行,没有任何问题,但我相信这背后一定有一些风险。有谁能给我举个好例子,说明这两种编译警告会导致一些意想不到的问题

同时,若这两个警告有潜在的风险,为什么c编译器允许出现这类警告,但不直接将它们设置为错误?有什么故事吗?

隐式声明。例如,您有一个函数:
float-foo(float-a)
,当您调用它时,它不会被声明。隐式规则将创建具有以下签名的自动声明:
intfoo(double)
(如果传递的参数是float)。所以您传递的值将转换为double,但
foo
需要
float
。与返回相同-调用代码需要
int
,但返回
float
。价值观将是一片混乱

枚举与其他类型混合。枚举类型具有它可以接受的值的列表。如果您试图为其指定数值,则它可能不是列出的值之一;如果以后您的代码只需要指定的范围,并且假定没有其他范围,则可能会出现错误行为。

简单示例:

文件:warn.c

#include <stdio.h>

double foo(double x)
{
  return myid(x);
}

int
main (void)
{
  double x = 1.0;
  fprintf (stderr, "%lg == %lg\n", x, foo (x));
  return 0;
}
编译并运行:

$ gcc warn.c foo.c -Wall
warn.c: In function ‘foo’:
warn.c:5: warning: implicit declaration of function ‘myfabs’
$ ./a.out 
1 == 0

旧的C标准(C90)有一个奇怪的“default int”规则,而且为了兼容性,即使在最新的编译器中也支持它。

ok,那么我可以知道为什么C编译器允许默认的
隐式声明
?这背后有什么故事吗?因为历史原因。历史原因是有答案的。C99+禁止隐式声明。C++也一样。不要把警告看成是风险,而是有用的帮助。始终启用所有这些(
gcc-Wall-Wextra
),并始终改进代码以避免它们。有时你会出现误报。其中大多数都不是错误,因为C99标准要求这样做。当心这可能不是现在的问题,但在将来。几周后,您希望更改代码中的某些内容。若你们已经解决了所有的警告,编译器会告诉你们,你们的新修改可能以某种方式被破坏或错误。假设您在新版本中将参数添加到foo函数中。有了在头文件中声明的函数,编译器会告诉你们,你们必须在所有地方纠正它,但若并没有它,它会编译,但不能正常工作。
$ gcc warn.c foo.c -Wall
warn.c: In function ‘foo’:
warn.c:5: warning: implicit declaration of function ‘myfabs’
$ ./a.out 
1 == 0