我遇到了这个 * 问题 *,我不知道如何评估它,因为我刚刚开始学习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'
和0
(NULL
)之间的区别,以及为什么我应该用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)
个
1条答案
按热度按时间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 *)0
或NULL
(或c23的nullptr
),会引起混淆。警戒(默认启用)被clang和gcc支持,以帮助识别潜在的程序员错误。然而clang的实现更完整:clang检测到
'\0'
在赋值表达式中的错误使用,而不是像gcc那样仅用于比较。很可能考试系统使用了clang,不是gcc(它似乎也运行在windows上,但两个编译器都可用于此目标)。有关编译器版本的比较,请参阅this godbolt session。例如,请注意,这样写是不正确的:
字符串
或甚至
型
因为这些空
int
值不会像execl
期望的那样作为char *
值传递。此外,char
指针和int
在大多数64位体系结构上具有不同的表示。你必须写:
型
或
型