我目前正使用Linux Mint
在我的计算机上运行GCC-5.3
,因为默认包含C11
。
我开始为自己学习C
只是为了好玩,当时GCC
版本是4.8
,如果我没记错的话。
如果在以下程序中使用带有GCC-4.8
标记的-pedantic
,则无论如何:
#include <stdio.h>
#include <string.h>
int main(void){
char *arr = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
size_t length = strlen(arr);
printf("Length of Arr = %zu\n",length);
}
在编译时,会收到以下警告:
program.c: In function ‘main’:
program.c:5:5: warning: string length ‘510’ is greater than the length ‘509’ ISO C90 compilers are required to support [-Woverlength-strings]
char *arr = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
^
program.c:7:5: warning: ISO C90 does not support the ‘z’ gnu_printf length modifier [-Wformat=]
printf("Length of Arr = %zu\n",length);
^
program.c:8:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
如果我们看到警告的这一部分:
warning: string length ‘510’ is greater than the length ‘509’ ISO C90 compilers are required to support [-Woverlength-strings]
在某种程度上明确-pedantic
标志是一个问题所以我决定不使用它并避免它像避免-ansi
因为新的(最后)标准C11
。 / p>
现在,如果我使用GCC-5.3
编译相同的程序:
gcc-5 -Wall -pedantic program.c -o program
程序编译好,没有警告。
如果我尝试编译以下程序,现在基于以下问题Return void type in C and C++:
#include <stdio.h>
#include <string.h>
void f(void);
void f2(void);
int main(void){
f();
}
void f(void){
}
void f2(void){
return f();
}
以下内容:
gcc-5 -Wall -pedantic program.c -o program
我明白了:
program.c: In function ‘f2’:
program.c:16:16: warning: ISO C forbids ‘return’ with expression, in function returning void [-Wpedantic]
return f();
^
但是如果没有'迂腐'的旗帜就可以编好。这对我来说很困惑。
这告诉我,我确实需要-pedantic
标志,但我并不痛。
所以,我的问题是,我们是否需要再次使用 -pedantic
<{1}}?
答案 0 :(得分:10)
如果您需要它,您需要它。如果你没有,你就不会。
gcc&#39; -pedantic
选项告诉它严格执行您要求的C标准规则。这会导致其他警告消息(如果您使用-pedantic-errors
,则会导致致命错误。)
问题是,您是否希望编译器警告您违反C标准要求的代码?
如果您希望代码尽可能便携,请使用-pedantic
并密切关注它告诉您的任何内容。如果您希望代码依赖于非标准功能,请不要使用-pedantic
- 但是您可能会面临使用不同编译器和/或不同目标系统编译代码的风险
您遇到的具体信息适用于C90和C11之间发生变化的事件。 C11要求编译器在字符串文字中支持至少4095个字符; C90只需要509.(实际上,对于gcc,实际限制不是固定的,而是由编译时的可用内存强加的。标准中描述限制的方式并不那么简单,但我赢了进入那个。)但是,你很少需要一个字符串文字很长。
C99添加了%zu
格式,用于打印size_t
类型的值。如果您希望您的代码可以移植到C99之前的实现,那么您需要避免使用它;例如,您可以使用printf("%lu\n", (unsigned long)sizeof foo)
。实际上,大多数当前的实现都支持%zu
。
在使用return
返回类型定义的函数中,不允许带有表达式的void
语句,甚至类型为void
的表达式。这是你应该想要的警告(恕我直言)。
底线:如果要严格执行C标准的规则,请使用-pedantic
。如果您不想这样做,请不要使用-pedantic
。 (但考虑使用-pedantic
编译代码,至少偶尔会清除它检测到的任何实际错误,以及您可能不关心的警告。)
答案 1 :(得分:5)
最初的C C89 / C90标准只要求编译器允许字符串文字长达509个字节。使用长度超过509字节的字符串编译为C90标准的代码不是最大可移植的;符合标准的编译器可以拒绝代码。它在实践中不太可能成为问题,但理论上可能会发生。
限制在C99中提高到4095字节(并且在C11中保持不变)。因此,您必须使用更长的字符串才能使用C99或C11来破坏限制。
GCC 4.x编译器默认使用C90标准。 GCC 5.x编译器默认使用C11标准。因此,在GCC 4.x下使用-pedantic
进行编译时,不能最大程度地移植到C90的代码将生成警告,但不会生成与GCC 5.x相同的警告,除非该构造也不能移植到所有C11编译器 - 除非它也违反了C11编译时限制之一。
-pedantic
标志有其用途。例如,昨天有人遇到问题,因为他们正在使用:
void *p = malloc(sizeof(*p));
根据标准,这是错误的代码,但GCC(5.3.0经过专门测试,但其他5.x和4.x版本的行为相同)允许它,将sizeof(*p)
解释为{{1} }。这对其他编译器来说是不可移植的。使用1
报告问题;不使用-pedantic
没有。
答案 2 :(得分:2)
从正式的角度来看,如果您打算用标准C编写代码,那么肯定需要-pedantic
标志(此外,-pedantic-errors
可能更好一点)。但是,-pedantic
的原始实现遭遇了一个相当可疑的设计决策:它包含与实现限制相关的警告(可以),最重要的是它还在-pedantic-errors
模式下将它们变为错误(在我看来,这是不可接受的)。
有关实现限制的警告可能很有用,但仍然可以保持它们独立可控,保持-pedantic
保留用于直接约束违规。
您不再看到有关-pedantic
的实施限制的警告这一事实可能意味着GCC 5最终决定处理此问题。如果是这样,那将是一个值得欢迎的改变(但更可能是改变的限制)。
答案 3 :(得分:1)
-pedantic只是一个标志,可以打开一大堆警告和错误,如果你愿意,你可以使用它,但听起来你真的没有使用c11,否则它不会给那个特别警告......
尝试:
gcc -std=c11 -Wall -pedantic program.c -o program
这将使pre gcc-5版本使用C11 std作为默认值而不是gnu89
The default mode for C is now -std=gnu11 instead of -std=gnu89
答案 4 :(得分:0)
错误消息末尾的[-Wpedantic]
表示警告是由-pedantic
编译器选项生成的。换句话说,-pedantic
已启用。
答案 5 :(得分:-3)
您不需要-pedantic
标志。几乎没有人需要-pedantic
标志。
Pedantry - 过度关注细微的细节和规则。
实际上,根据定义,可以忽略 -pedantic
个警告。在编写跨平台代码时,该标志可能很有用,但就是这样。