为什么Ubuntu上的gcc不警告-Wnon-literal-null-conversion,但在macOS上?

utugiqy6  于 11个月前  发布在  Mac
关注(0)|答案(1)|浏览(148)

我遇到了这个 * 问题 *,我不知道如何评估它,因为我刚刚开始学习C和gcc。我创建了一个函数来返回一个以null结尾的字符串数组。字符串以'\0'结尾,但数组也以'\0'结尾。这工作得很好 * 因为它没有警告我在Ubuntu上的标志-Wall -Werror -Wextra,但当我尝试与macOS它无法编译(expression which evaluates to zero treated as a null pointer constant of type 'char *' [-Werror,-Wnon-literal-null-conversion])。
所以,我读到了'\0'0NULL)之间的区别,以及为什么我应该用NULL终止数组。我的问题是我如何在Ubuntu上也能捕捉到它?什么默认设置使它们之间有这种区别?
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Apple clang version 15.0.0 (clang-1500.1.0.2.5)

ntjbwcob

ntjbwcob1#

macOS上的默认gcc的行为与linus上的gcc不同,因为它是一个完全不同的编译器:正如--version输出所证明的那样,macOS上的gcc默认情况下是clang的别名。

clang是作为X-Code的一部分安装的,支持gcc的大部分警告,以及更多。默认设置有些不同,所以你可能会在mac上得到一个警告,你不会在Linux上使用gcc

在Makefile中使用gcc -Wall -Wextra -Werror启用更多警告是一个好主意,可以在编译时捕获许多微妙和不那么微妙的问题。clang也支持**-Weverything**,但这种额外级别的分析可能有点讨厌。clang -Wall -Wextra启用了gcc缺少的一些警告。
在您的例子中,警告告诉您使用了一个字符常量'\0',它的类型为int,值为0,作为char *数组的空终止符。虽然'\0'将像0一样被视为空指针,使用字符常量代替更明确的空指针常量,如(char *)0NULL(或c23的nullptr),会引起混淆。
警戒(默认启用)被clanggcc支持,以帮助识别潜在的程序员错误。然而clang的实现更完整:clang检测到'\0'在赋值表达式中的错误使用,而不是像gcc那样仅用于比较。很可能考试系统使用了clang,不是gcc(它似乎也运行在windows上,但两个编译器都可用于此目标)。有关编译器版本的比较,请参阅this godbolt session
例如,请注意,这样写是不正确的:

execl("/bin/echo", "/bin/echo", "Hello world!\n", '\0');

字符串
或甚至

execl("/bin/echo", "/bin/echo", "Hello world!\n", 0);


因为这些空int值不会像execl期望的那样作为char *值传递。此外,char指针和int在大多数64位体系结构上具有不同的表示。
你必须写:

execl("/bin/echo", "/bin/echo", "Hello world!\n", NULL);


execl("/bin/echo", "/bin/echo", "Hello world!\n", (char *)0);

相关问题