我是否需要来自GCC和C11的-dantic旗帜?

时间:2016-03-14 17:48:57

标签: c gcc c11

我目前正使用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}}?

6 个答案:

答案 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

来自gcc.gnu.org/gcc-5/changes.html

并且进一步详细说明:c11和gnu11之间的区别是微妙的,我没有同样关注c11,但是在c99 / gnu99中,关系是gnu99是c11的超集并允许语言的一些编译器扩展......我非常怀疑这与c11 / gnu11

的关系是一样的

答案 4 :(得分:0)

错误消息末尾的[-Wpedantic]表示警告是由-pedantic编译器选项生成的。换句话说,-pedantic已启用。

答案 5 :(得分:-3)

您不需要-pedantic标志。几乎没有人需要-pedantic标志。

Pedantry - 过度关注细微的细节和规则。

实际上,根据定义,可以忽略

-pedantic个警告。在编写跨平台代码时,该标志可能很有用,但就是这样。