如何使gcc编译器不优化诸如printf之类的标准库函数调用? [英] How to get the gcc compiler to not optimize a standard library function call like printf?

查看:141
本文介绍了如何使gcc编译器不优化诸如printf之类的标准库函数调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于好奇,我想知道gcc是否可以通过某种方式不优化任何函数调用?

Out of curiosity, I was wondering if there is any way that gcc does not optimize any function calls?

在生成的汇编代码中,将printf函数替换为putchar.即使使用默认的 -O0 最小优化标志,也会发生这种情况.

In the generated assembly code, the printf function is replaced by putchar. This happens even with the default -O0 minimal optimization flag.

#include <stdio.h>

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

(

(Godbolt showing GCC9 doing it, clang8 keeping it unchanged.)

推荐答案

使用 -fno-builtin 禁用所有对等价的标准C函数的替换和内联.

Use -fno-builtin to disable all replacement and inlining of standard C functions with equivalents.

或将 -fno-builtin-FUNCNAME 用于特定功能,例如 -fno-builtin-printf .

Or use -fno-builtin-FUNCNAME for a specific function, like -fno-builtin-printf.

默认情况下,某些常用的标准C函数被视为内置函数,类似于 __ builtin_popcount .printf的处理程序将其替换为putchar或puts(如果可能). https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

By default, some commonly-used standard C functions are handled as builtin functions, similar to __builtin_popcount. The handler for printf replaces it with putchar or puts if possible. https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

默认情况下,不将诸如 printf("a")之类的C语句的实现细节视为可见的副作用,因此不会保留任何东西.您仍然可以在调用站点上设置断点并进入函数(至少在asm或如果安装了调试符号的情况下,在源代码模式下).

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. 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).

要禁用单个功能的其他类型的优化,请参见 __ attribute __((optimize(0)))上的功能 #pragma GCC优化.但要注意:

To disable other kinds of optimizations for a single function, see __attribute__((optimize(0))) on a function or #pragma GCC optimize. But beware:

optimize 属性应仅用于调试目的.它不适用于生产代码.

The optimize attribute should be used for debugging purposes only. It is not suitable in production code.


您不能禁用所有优化.gcc通过内部表示形式转换为asm的方式中,某些优化是固有的.请参见禁用GCC中的所有优化选项.


You can't disable all optimizations. Some optimization is inherent in the way gcc transforms through an internal representation on the way to asm. See Disable all optimization options in GCC.

例如即使在 -O0 时,gcc也会将 x/10 优化为乘法逆.

e.g. even at -O0 gcc will optimize x / 10 to a multiplicative inverse.

它仍将所有内容存储在C语句之间(用于一致调试; tcc .带有 -O0 的Clang和ICC比gcc更具文字性,MSVC调试模式也是如此.

It still stores everything to memory between C statements (for consistent debugging; that's what -O0 really means); gcc doesn't have a "fully dumb" mode that tries to transliterate C to asm as naively as possible. Use tcc for that. Clang and ICC with -O0 are somewhat more literal than gcc, and so is MSVC debug mode.

请注意, -g 永远不会对code-gen产生任何影响,而只会对发出的元数据产生影响.GCC使用其他选项(主要是 -O -f * -m * )来控制代码生成,因此您始终可以安全地进行操作除了较大的二进制文件外,还可以启用 -g 而不会影响性能.这不是调试 mode (即 -O0 ),而只是调试 symbols .

Note that -g never has any effect on code-gen, only on the metadata emitted. 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. It's not debug mode (that's -O0), it's just debug symbols.

这篇关于如何使gcc编译器不优化诸如printf之类的标准库函数调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆