提问人:William Pursell 提问时间:1/13/2011 更新时间:1/13/2011 访问量:294
应该在源代码中还是在 CPPFLAGS 中指定标准?
Should standards be specified in source code or in CPPFLAGS?
问:
#define _BSD_SOURCE 好还是设置 CPPFLAGS=-D_BSD_SOURCE 更好?
在我看来,如果一段源代码依赖于特定的标准,最好在代码本身中用 #define 明确地拼写出来。然而,很多评论认为,在编译行上指定标准更合适。从源代码中省略标准,只在编译时指定它有什么好处?
答:
6赞
Maxim Egorushkin
1/13/2011
#1
如果在源中指定定义,则存在相同的头文件可能包含在多个源文件(转换单元)中但具有不同预处理器定义的风险,这可能导致违反一个定义规则,这通常很麻烦调试。
通过为整个项目而不是在单个源文件中指定定义,可以最大限度地减少这种违反“一个定义规则”的可能性。
此外,如果需要添加新定义,则只需更改一个生成文件,而不是所有源文件。
评论
0赞
William Pursell
1/13/2011
但是,您可以为每个翻译单元使用不同的标准。如果整个项目都符合 C89 标准,除了一个 TU 使用 gnu 扩展名,那么 #define _GNU_SOURCE 那个文件不是比玷污整个项目更好吗?这样,如果我在其他 TU 中使用依赖于比 C89 更现代标准的函数,但我不知道这种依赖性,我会在编译时知道它。如果整个项目都依赖于现代标准,那么消除依赖性就会变得更加困难。
0赞
Maxim Egorushkin
1/13/2011
我必须承认,我从来没有在一个二进制文件中混合和匹配需要不同标准(或预处理器定义)的源。如果我这样做了,我仍然会在 makefile 中指定该特定源的标志(作为特定于目标的变量),因为我的所有编译器标志都在 makefile 中的一个位置。此外,我经常在不同的平台上使用不同的编译器(g++、SunCC)编译我的源代码,因此它是特定于平台的 makefile 来适应特定于平台的定义。
1赞
Chris Dodd
1/14/2011
@William:问题在于,如果你试图在不同的翻译单元中混合不同的标准,就不能保证你可以安全地将生成的对象链接到一个可执行文件中。它可能有效,也可能失败,或者可能看起来有效,但会在运行时为您提供微妙的、难以诊断的问题。
0赞
Ioan
1/14/2011
您还可以为那些在 makefile 中需要不同定义的翻译单元使用特定目标。
评论