2017-08-16 55 views
0

使用-std=gnu99 GCC,下面的代码编译:如何指定gcc {C}中的init不应该编译?

void f() 
{ 
    struct X data = {}; 
    // do something with data 
} 

这是合法的C? 这是一个GNU扩展?

如何告诉gcc不接受这种init?

欲确保与其他编译器(例如像视觉2015)兼容性

+0

你想用'{}'做什么?初始化'data'的内容? – naccyde

+0

是(像{0}这是有效的C)。问题在于团队每天都使用C++/C,并且很容易有人不经过思考就使用它(即使在C++中,这也会是struct X data {};) – Tic

回答

3

如果你想拒绝含有特定的GNU的扩展代码,使用-std=c99 -pedantic-errors-pedantic会发出非标准扩展的诊断,但不一定会直接拒绝这个代码) 。但是,如果您想要保证ISO一致性,请注意这不是100%的解决方案。从gcc手册页:

一些用户尝试使用-pedantic检查严格的ISO C标准的程序。他们很快就发现它并不完全符合他们的要求:它找到了一些非ISO实践,但不是全部 - 只有ISO C需要诊断的那些实践,以及一些已经添加了诊断的实践。

报告任何不符合ISO C的功能在某些情况下可能会有用,但需要大量的额外工作,并且与-pedantic会有很大不同。我们不打算在不久的将来支持这种功能。

+0

这就是说,gcc用' -std = c11 -pedantic-errors'可能是有史以来最严格的C编译器。 – Lundin

3

否,空初始值设定不是标准C.它是一个gcc扩展。 See this的详细说明。

通过指定-std=gnu99,您允许使用GNU扩展。通过指定-std=cXX选项,可以强制编译器仅允许使用标准符合代码。那些

gcc online manual重点矿山

-std=

编译器可以接受几个基本标准,如 'C90' 或 'C++ 98',和方言GNU标准,如'gnu90'或'gnu ++ 98'。 当指定一个基本标准时,编译器会接受遵循该标准的所有程序,以及那些使用不违背GNU扩展的程序。例如,-std = c90关闭了与ISO C90不兼容的GCC的某些功能,例如asm和typeof关键字,但不包括ISO C90中没有含义的其他GNU扩展,例如省略中间项一个?:表达式。另一方面,当指定一个标准的GNU方言时,即使这些功能改变了基本标准的含义,编译器支持的所有功能也被启用。因此,一些严格遵守的程序可能会被拒绝。这个特定的标准被-Wpedantic用来确定哪些特征是给定该版本标准的GNU扩展。例如-std = gnu90 -Wpedantic会警告C++风格的'//'注释,而-std = gnu99 -Wantantic不会。

3

-pedantic选项将导致在这种情况下,要显示一个警告,-Werror将导致所有的警告被视为错误。

例如:

x1.c: In function ‘f’: 
x1.c:11:19: error: ISO C forbids empty initializer braces [-Werror=pedantic] 
    struct X data = {};