C 在调试模式下获得警告,但不在发布模式下(我是否获得未定义的行为?)
我有一点奇怪的情况。我正在某种设备上编译。 如果我在发布模式下编译,例如C 在调试模式下获得警告,但不在发布模式下(我是否获得未定义的行为?),c,C,我有一点奇怪的情况。我正在某种设备上编译。 如果我在发布模式下编译,例如 makeCore projectname release exe 一切都很好。如果我在调试模式下编译: makeCore projectname debug exe 我得到以下警告: src/administration.c: In function 'SetIp': src/administration.c:1409: warning: implicit declaration of function 'InputI
makeCore projectname release exe
一切都很好。如果我在调试模式下编译:
makeCore projectname debug exe
我得到以下警告:
src/administration.c: In function 'SetIp':
src/administration.c:1409: warning: implicit declaration of function 'InputIp'
问:这是否意味着在发布模式下使用我的应用程序是安全的
为什么会有这种行为?怎么办?我使用的是在发布模式下编译的二进制文件,我应该担心吗
编辑:我是否应该首先检查此编译器符合哪个C标准,如果它是C89之前的版本,那么我不必担心,因为它不是未定义的行为,对吗
Edit2:我的最终问题是我是否触发了未定义的行为,以及如何检查我是否触发了未定义的行为?我不确定我的编译器是实现C89还是C90等。。也许我应该问供应商,这是否是我上面所做的未定义的行为
更新:
这是函数签名:
s32 InputIp(s32 line, u8 * text, s32 otherline, u8 *IP, u8 coordx, s32 coordy);
这就是它的名称:
s32 res = InputIp(someconstant, u8pointer, otherconstant, otheru8pointer, integer1, integer2);
最后一个问题:既然我首先得到了这个警告,我能确定我使用的是使用C89的编译器吗?否则会是错误吗?我说得对吗?尽量准时回答:
这是否意味着在发布模式下使用我的应用程序是安全的
:警告意味着编译器无法找到InputIp
函数原型。这两种二进制风格之间的应用程序运行时行为(由此警告引起)不存在差异。您应该按照3
上的建议进行修复为什么会出现这种行为
:编译器标志似乎在Makefile中根据您传递给make…
怎么办?
:为InputIp
添加缺少的函数原型,然后重新构建应用程序我使用的是在发布模式下编译的二进制文件,我应该担心吗?
:在调试模式下编译的应用程序和在发布模式下编译的应用程序之间不应该存在由您的问题引发的运行时差异。您应该按照3
我是否应该首先检查一下这个编译器符合哪个C标准
:C89/C90标准与您的问题无关试图提供准时的答案:
这是否意味着在发布模式下使用我的应用程序是安全的
:警告意味着编译器无法找到InputIp
函数原型。这两种二进制风格之间的应用程序运行时行为(由此警告引起)不存在差异。您应该按照3
上的建议进行修复为什么会出现这种行为
:编译器标志似乎在Makefile中根据您传递给make…
怎么办?
:为InputIp
添加缺少的函数原型,然后重新构建应用程序我使用的是在发布模式下编译的二进制文件,我应该担心吗?
:在调试模式下编译的应用程序和在发布模式下编译的应用程序之间不应该存在由您的问题引发的运行时差异。您应该按照3
我是否应该首先检查一下这个编译器符合哪个C标准
:C89/C90标准与您的问题无关您不应该依赖,但是如果
InputIp
被定义为intinputip()
你应该没事。你不应该依赖,但是如果InputIp
被定义为intinputip()代码>你应该很好。有几个可能的原因可以解释为什么你会有不同
在发布版本中降低编译器警告级别
这是最可能的原因
条件代码
原因可能是这样的:
`#ifndef DEBUG`
`#include "ip.h"`
`#endif`
请注意,隐式声明
是一个警告,您应该认真对待,因为它可能隐藏bug。我建议您在需要的地方添加转发声明。有几个可能的原因可以解释为什么会有不同
在发布版本中降低编译器警告级别
这是最可能的原因
条件代码
原因可能是这样的:
`#ifndef DEBUG`
`#include "ip.h"`
`#endif`
请注意,隐式声明
是一个警告,您应该认真对待,因为它可能隐藏bug。我建议您在需要的地方添加前向声明。在C89中,如果函数是这样的原型(并且此原型在函数体的点处可见,或者函数体使用相同的原型):
假设u8
为8位类型,则在范围内没有原型的情况下调用此函数会导致未定义的行为
这种情况下的规则(调用范围中没有原型的原型函数)是所有参数和返回值必须在默认参数下保持不变
这些提升与变量函数中匹配..
的参数应用的提升相同,它们是:
- 任何级别低于
int
的整数类型都将提升为int
float
升级为double
- 所有其他类型保持不变
因此,u8
将在默认参数下更改为int
在C99中,调用范围中没有声明的函数是格式错误的
我强烈建议修复代码,以便使用范围内的原型调用函数。在C89中,如果函数是这样的原型(并且此原型在函数体的点可见,或者函数体使用相同的原型):
假设u8
是8位ty