如何防止gcc优化C中的一些语句?

时间:2010-02-08 05:50:24

标签: c gcc

为了使页面变脏(打开页表项中的脏位),我触摸页面的第一个字节,如下所示:

pageptr[0] = pageptr[0];

但在实践中,gcc将忽略死店淘汰的陈述。为了防止gcc优化它,我重新编写语句如下:

volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;

似乎这个伎俩有效,但有些难看。我想知道是否有任何指令或语法具有相同的效果?而且我不想使用-O0标志,因为它也会带来很大的性能损失。

3 个答案:

答案 0 :(得分:161)

您可以使用

#pragma GCC push_options
#pragma GCC optimize ("O0")

your code

#pragma GCC pop_options

禁用自GCC 4.4以来的优化。

如果您需要更多详细信息,请参阅GCC文档。

答案 1 :(得分:118)

您也可以根据需要使用__attribute__((optimize("O0"))),而不是使用新的pragma。这样做的好处是只应用于单个函数,而不是同一文件中定义的所有函数。

用法示例:

void __attribute__((optimize("O0"))) foo(unsigned char data) {
    // unmodifiable compiler code
}

答案 2 :(得分:79)

关闭优化可以解决问题,但这是不必要的。更安全的替代方法是使编译器使用volatile类型限定符来优化存储是非法的。

// Assuming pageptr is unsigned char * already...
unsigned char *pageptr = ...;
((unsigned char volatile *)pageptr)[0] = pageptr[0];

volatile类型限定符指示编译器严格关于内存存储和加载。 volatile的一个目的是让编译器知道内存访问有副作用,因此必须保留。在这种情况下,存储具有导致页面错误的副作用,并且您希望编译器保留页面错误。

这样,周围的代码仍然可以进行优化,并且您的代码可以移植到其他不了解GCC的#pragma__attribute__语法的编译器。