简体   繁体   English

如何使gcc编译器不优化诸如printf之类的标准库函数调用?

[英]How to get the gcc compiler to not optimize a standard library function call like printf?

Out of curiosity, I was wondering if there is any way that gcc does not optimize any function calls? 出于好奇,我想知道gcc是否可以通过某种方式不优化任何函数调用?

In the generated assembly code, the printf function is replaced by putchar. 在生成的汇编代码中,printf函数由putchar代替。 This happens even with the default -O0 minimal optimization flag. 即使使用默认的-O0最小优化标志,也会发生这种情况。

#include <stdio.h>

int main(void) {
    printf("a");
    return 0;
}

( Godbolt showing GCC9 doing it, clang8 keeping it unchanged.) Godbolt显示GCC9正在执行此操作,clang8使其保持不变。)

Use -fno-builtin to disable all replacement and inlining of standard C functions with equivalents. 使用-fno-builtin可以禁用所有标准C函数的替换和内联操作。

Or use -fno-builtin-FUNCNAME for a specific function, like -fno-builtin-printf . 或将-fno-builtin-FUNCNAME用于特定功能,例如-fno-builtin-printf

By default, some commonly-used standard C functions are handled as builtin functions, similar to __builtin_popcount . 默认情况下,某些常用的标准C函数被作为内置函数处理,类似于__builtin_popcount The handler for printf replaces it with putchar or puts if possible. printf的处理程序将其替换为putchar或puts(如果可能)。 https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

The implementation details of a C statement like printf("a") are not considered a visible side-effect by default, so aren't something that gets preserved. 默认情况下,不会将诸如printf("a")类的C语句的实现细节视为可见的副作用,因此不会保留任何东西。 You can still set a breakpoint at the call-site and step into the function (at least in asm, or in source mode if you have debug symbols installed). 您仍然可以在调用站点上设置断点并进入函数(至少在asm或如果安装了调试符号的情况下,在源代码模式下)。


To disable other kinds of optimizations for a single function, see __attribute__((optimize(0))) on a function or #pragma GCC optimize . 要为单个函数禁用其他类型的优化,请参见函数上的__attribute__((optimize(0)))#pragma GCC optimize But beware: 但要注意:

The optimize attribute should be used for debugging purposes only. optimize属性应仅用于调试目的。 It is not suitable in production code. 它不适用于生产代码。


You can't disable all optimizations. 您不能禁用所有优化。 Some optimization is inherent in the way gcc transforms through an internal representation on the way to asm. gcc通过内部表示形式转换为asm的方式中固有的一些优化。 See Disable all optimization options in GCC . 请参阅禁用GCC中的所有优化选项

eg even at -O0 gcc will optimize x / 10 to a multiplicative inverse. 例如,即使在-O0 gcc也会将x / 10优化为乘法逆。

It still stores everything to memory between C statements (for consistent debugging; that's what -O0 really means ); 它仍然将所有内容存储在C语句之间(用于一致调试; 这是-O0真正含义 ); gcc doesn't have a "fully dumb" mode that tries to transliterate C to asm as naively as possible. gcc没有尝试完全将C音译为asm的“完全哑”模式。 Use tcc for that. 为此使用tcc Clang and ICC with -O0 are somewhat more literal than gcc, and so is MSVC debug mode. Clang和带有-O0 ICC比gcc的字面意义更大,MSVC调试模式也是如此。

Note that -g never has any effect on code-gen, only on the metadata emitted. 请注意, -g永远不会对代码生成产生任何影响,仅会对发出的元数据起作用。 GCC uses other options (mostly -O , -f* , and -m* ) to control code-gen, so you can always safely enable -g without hurting performance, other than a larger binary. GCC使用其他选项(主要是-O-f*-m* )来控制代码生成,因此,除了较大的二进制文件外,您始终可以安全地启用-g而不会影响性能。 It's not debug mode (that's -O0 ), it's just debug symbols . 这不是调试模式 (即-O0 ),而仅仅是调试符号

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM