是否可以使用 GCC 编译具有特定编译器标志的代码文件的一部分?

Posted

技术标签:

【中文标题】是否可以使用 GCC 编译具有特定编译器标志的代码文件的一部分?【英文标题】:Is it possible to use GCC to compile one section of a code file with specific compiler flags? 【发布时间】:2017-07-07 19:41:14 【问题描述】:

例如,假设我有一些正在测试的功能。我希望这些功能严格遵守标准合规性,所以我想用 --pedantic 标志编译它们。但是进行测试的代码在编译时会发出很多警告。有没有办法用--pedantic 编译那些特定的函数?

或者,假设我有一个精心编写但极其昂贵的函数,需要尽可能快地运行。如何使用 -Ofast 编译该函数(以及其他一些函数),并使用 -O2 或 -O3 编译程序的其余部分?

【问题讨论】:

将这些函数放在单独的文件中并使用单独的标志构建它们 - 将是简单的解决方案。 “执行测试的代码会发出很多警告” - 所以已经修复它们 - 不要等待或找借口 - 修复编译器警告(并开始使用 -Werror 构建)。 GCC - Enable compiler flags only on specific functions的可能重复 【参考方案1】:

实际上有使用#pragma optimize 语句,或者使用__attribute__((optimize("-O3"))) 所有优化选项都可以找到here。

一个简单的例子是:

#include <stdio.h>


// Using attribute
__attribute__((optimize("-O3"))) void fast_function_attribute()

    printf("Now calling a slow function, compiled with -O3 flags.\n");



__attribute__((optimize("-O1"))) void slow_function_attribute()

    printf("Now calling a slow function, compiled with -O1 flags.\n");



// Using #pragma
#pragma GCC push_options
#pragma GCC optimize ("-O3")


void fast_function_pragma()

    printf("This will be another fast routine.\n");



#pragma GCC pop_options


#pragma GCC push_options
#pragma GCC optimize ("-O1")


void slow_function_pragma()

    printf("This will be another slow routine.\n");



#pragma GCC pop_options


int main(void)

    fast_function_attribute();
    slow_function_attribute();
    fast_function_pragma();
    slow_function_pragma();

如果您使用不同的编译器,我强烈建议您使用宏包装它们(或使用 pragma 语句而不是 __attribute__ 以避免任何编译器警告。

【讨论】:

【参考方案2】:

是的。

#include <iostream>

#pragma GCC diagnostic push
#pragma GCC diagnostic warning "-Wpedantic"
#pragma GCC push_options
#pragma GCC optimize ("O0")
void bob()
  std::cerr<<"Sandwich maker!"<<std::endl;

#pragma GCC diagnostic pop
#pragma GCC pop_options

int main()
  bob();

push_optionsdiagnostic push 分别保存优化和诊断标志,然后将它们更改为 pedantic 和 O0(或 O1O2O3Os、@987654331 @)。 pop pragma 恢复原始设置。

有关优化 pragma 的更多详细信息是 here,有关诊断 pragma 的详细信息是 here。

【讨论】:

【参考方案3】:

GCC 在某些情况下允许这样做,但不是全部。

对于优化选项,您可以使用optimize function attribute 或equivalent #pragma directive。

对于警告选项,它不太可靠。我认为它只有a pragma 而不是函数属性,而且它显然不支持所有警告。

对于警告或优化以外的选项,除了使用单独的文件之外,我不知道有什么方法可以做到这一点。

【讨论】:

以上是关于是否可以使用 GCC 编译具有特定编译器标志的代码文件的一部分?的主要内容,如果未能解决你的问题,请参考以下文章

Windows XP 的 Mingw GCC 交叉编译

Valgrind 标志,调试与发布编译

使用 -g gcc 标志编译的程序是不是比不使用 -g 编译的同一程序慢?

是否可以从 gcc 的源代码中确定或设置编译器选项?

默认 gcc 编译器选项是 gcc 版本特定还是操作系统特定或两者兼而有之?

GCC - 包含编译标志的宏