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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2219829/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:24:57  来源:igfitidea点击:

How to prevent gcc optimizing some statements in C?

cgcc

提问by ZelluX

In order to make a page dirty (switching on the dirty bit in the page table entry), I touch the first bytes of the page like this:

为了使页面变脏(打开页表条目中的脏位),我像这样触摸页面的第一个字节:

pageptr[0] = pageptr[0];

But in practice gcc will ignore the statement by dead store elimination. In order to prevent gcc optimizing it, I re-write the statement as follows:

但是在实践中 gcc 会通过死存储消除来忽略该语句。为了防止gcc对其进行优化,我将语句改写如下:

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

It seems the trick works, but somewhat ugly. I would like to know is there any directives or syntax which has the same effect? And I don't want to use a -O0flag, since it will bring great performance penalty as well.

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

采纳答案by Dietrich Epp

Turning off optimization fixes the problem, but it is unnecessary. A safer alternative is to make it illegal for the compiler to optimize out the store by using the volatiletype qualifier.

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

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

The volatiletype qualifier instructs the compiler to be strict about memory stores and loads. One purpose of volatileis to let the compiler know that the memory access has side effects, and therefore must be preserved. In this case, the store has the side effect of causing a page fault, and you want the compiler to preserve the page fault.

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

This way, the surrounding code can still be optimized, and your code is portable to other compilers which don't understand GCC's #pragmaor __attribute__syntax.

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

回答by Plow

You can use

您可以使用

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

your code

#pragma GCC pop_options

to disable optimizations since GCC 4.4.

自 GCC 4.4 起禁用优化。

See the GCC documentation if you need more details.

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

回答by FRob

Instead of using the new pragmas, you can also use __attribute__((optimize("O0")))for your needs. This has the advantage of just applying to a single function and not all functions defined in the same file.

除了使用新的编译指示外,您还可以__attribute__((optimize("O0")))根据自己的需要使用。这具有仅适用于单个函数而不是同一文件中定义的所有函数的优点。

Usage example:

用法示例:

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