使用 gcc 返回 NULL 时没有警告
No warning when returning NULL with gcc
使用 gcc
5.2.0,我注意到此代码不会生成警告:
#include <stddef.h>
int function(void)
{
return NULL;
}
void procedure(void)
{
return NULL;
}
我使用了标志 -Wall -Wextra -std=c99 -pedantic
,我是 运行 archlinux。我不确定为什么此代码在 gcc
上运行良好,尤其是因为 clang
3.7.0 确实会生成警告。
我也尝试过旧版本的 gcc
,例如 4.9 或 4.7,它们都会生成警告。
警告是:
warning: return makes integer from pointer without a cast
和
warning: ‘return’ with a value, in function returning void
我应该提一下,我尝试在 Debian 上编译 gcc 5.2,结果是一样的。所以archlinux好像不是问题。
理由是什么?我似乎无法在其他任何地方找到与此相关的任何内容。
谢谢!
第一个函数的有效性取决于 NULL
的定义方式。如果 NULL
定义为 0
,那么第一个函数没有问题。但是,如果它恰好被定义为 (void *) 0
(在 C 代码中通常是这种情况),则第一个函数将无效。 GCC 通常对隐式指针到整数的转换非常宽容。
第二个函数完全无效。语言规范明确指出 "A return statement with an expression shall not appear in a function whose return type is void." 如果它编译,那一定是 GCC 对某些事情过于宽容的另一个例子。
如果您希望其诊断输出与标准 C 语言相关,则需要 运行 GCC -pedantic
模式。在默认模式下,它不是一个可靠的 C 编译器(至少在它的诊断输出中),而且它 "does not issue a warning" 的事实绝对没有任何意义。
然而,在我的实验中,即使使用 -std=
和 -pedantic
开关,我也无法让 GCC 抱怨第二个函数。看起来像是编译器中的错误。
这似乎是 gcc 5.2.0 中的回归——据我所知,这是一个奇怪的回归。
对于 gcc 4.4.5 和 4.8.4,程序(在添加所需的 #include <stddef.h>
之后)会在两个 return NULL;
语句上产生警告,即使没有任何额外的命令行选项。
对于 gcc 5.2.0,即使是 gcc -c -Wall -Wextra -std=c99 -pedantic
也不会产生警告。对于第二个 returns 来自 void
函数的值,必须进行诊断。
现在是奇怪的部分。
$ gcc --version | head -n 1
gcc (GCC) 5.2.0
$ cat c.c
#include <stddef.h>
int function(void) {
#ifdef USE_NULL
return NULL;
#else
return ((void*)0);
#endif
}
void procedure(void) {
#ifdef USE_NULL
return NULL;
#else
return ((void*)0);
#endif
}
$ gcc -c c.c
c.c: In function ‘function’:
c.c:7:12: warning: return makes integer from pointer without a cast [-Wint-conversion]
return ((void*)0);
^
c.c: In function ‘procedure’:
c.c:15:12: warning: ‘return’ with a value, in function returning void
return ((void*)0);
^
$ gcc -c -DUSE_NULL c.c
$
定义 USE_NULL
时,不会产生任何警告。使用 gcc -E -DUSE_NULL
编译(将预处理器的输出打印到标准输出)确认 NULL
被定义为 ((void*)0)
。但是当我用 ((void*)0)
替换 NULL
时,会产生警告(因为它们应该是)。
我不知道发生了什么。一旦宏 NULL
被扩展,它应该与 ((void*)0)
没有区别,但编译器的行为会根据使用的宏而改变。
我在这里填写了错误报告:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67730
已确认,似乎已修复 5.3!
感谢您的帮助。
使用 gcc
5.2.0,我注意到此代码不会生成警告:
#include <stddef.h>
int function(void)
{
return NULL;
}
void procedure(void)
{
return NULL;
}
我使用了标志 -Wall -Wextra -std=c99 -pedantic
,我是 运行 archlinux。我不确定为什么此代码在 gcc
上运行良好,尤其是因为 clang
3.7.0 确实会生成警告。
我也尝试过旧版本的 gcc
,例如 4.9 或 4.7,它们都会生成警告。
警告是:
warning: return makes integer from pointer without a cast
和
warning: ‘return’ with a value, in function returning void
我应该提一下,我尝试在 Debian 上编译 gcc 5.2,结果是一样的。所以archlinux好像不是问题。
理由是什么?我似乎无法在其他任何地方找到与此相关的任何内容。
谢谢!
第一个函数的有效性取决于 NULL
的定义方式。如果 NULL
定义为 0
,那么第一个函数没有问题。但是,如果它恰好被定义为 (void *) 0
(在 C 代码中通常是这种情况),则第一个函数将无效。 GCC 通常对隐式指针到整数的转换非常宽容。
第二个函数完全无效。语言规范明确指出 "A return statement with an expression shall not appear in a function whose return type is void." 如果它编译,那一定是 GCC 对某些事情过于宽容的另一个例子。
如果您希望其诊断输出与标准 C 语言相关,则需要 运行 GCC -pedantic
模式。在默认模式下,它不是一个可靠的 C 编译器(至少在它的诊断输出中),而且它 "does not issue a warning" 的事实绝对没有任何意义。
然而,在我的实验中,即使使用 -std=
和 -pedantic
开关,我也无法让 GCC 抱怨第二个函数。看起来像是编译器中的错误。
这似乎是 gcc 5.2.0 中的回归——据我所知,这是一个奇怪的回归。
对于 gcc 4.4.5 和 4.8.4,程序(在添加所需的 #include <stddef.h>
之后)会在两个 return NULL;
语句上产生警告,即使没有任何额外的命令行选项。
对于 gcc 5.2.0,即使是 gcc -c -Wall -Wextra -std=c99 -pedantic
也不会产生警告。对于第二个 returns 来自 void
函数的值,必须进行诊断。
现在是奇怪的部分。
$ gcc --version | head -n 1
gcc (GCC) 5.2.0
$ cat c.c
#include <stddef.h>
int function(void) {
#ifdef USE_NULL
return NULL;
#else
return ((void*)0);
#endif
}
void procedure(void) {
#ifdef USE_NULL
return NULL;
#else
return ((void*)0);
#endif
}
$ gcc -c c.c
c.c: In function ‘function’:
c.c:7:12: warning: return makes integer from pointer without a cast [-Wint-conversion]
return ((void*)0);
^
c.c: In function ‘procedure’:
c.c:15:12: warning: ‘return’ with a value, in function returning void
return ((void*)0);
^
$ gcc -c -DUSE_NULL c.c
$
定义 USE_NULL
时,不会产生任何警告。使用 gcc -E -DUSE_NULL
编译(将预处理器的输出打印到标准输出)确认 NULL
被定义为 ((void*)0)
。但是当我用 ((void*)0)
替换 NULL
时,会产生警告(因为它们应该是)。
我不知道发生了什么。一旦宏 NULL
被扩展,它应该与 ((void*)0)
没有区别,但编译器的行为会根据使用的宏而改变。
我在这里填写了错误报告:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67730
已确认,似乎已修复 5.3!
感谢您的帮助。