提问者:小点点

使用常量bool删除调试信息时的编译器优化


我有一个带有调试函数的类,名为log(std::strings)。我在一个小型嵌入式系统上工作,因此我想从二进制文件中删除不必要的字符串。

我可以使用#define来实现我想要的目标,但我认为这是一种糟糕的做法。 使用-os优化,我认为我可以使用常量bool,如下所示:

#include <cstdio>
#include <string>
#include <iostream>

class test
{
    const bool enable_debug = false;
    void log(std::string s)
    {
        if (enable_debug) printf("%s",s.c_str());
    }

public:
    void doStuff(int i)
    {
        log("I don't want this string to appear in the binary output");
    }
};

int main()
{
    test instance;
    char input;
    std::cin>>input;
    instance.doStuff(input);
}

请看一下这里的输出:https://godbolt.org/z/qz7csf。 正如您所看到的,字符串不会从assemby生成的代码中移除,即使没有办法使用它,因为enable_debug是一个常量。

  1. 那么为什么它仍然在输出中?
  2. 如何在不使用#define的情况下创建切换开关?

PS:最后,我想把bool变量放在类的外部,以便同时切换我所有的类。


共2个答案

匿名用户

您使用的是std::string。 编译器不够聪明,无法看穿所有的std::string机制,我甚至怀疑它是否允许消除std::string构造。 由于字符串文字用于初始化std::string,因此也不能消除该文字。

如果您想节省几个字节,也许可以考虑使用const char*

匿名用户

  1. 那么为什么它仍然在输出中?

因为编译器没有进行足够深入的分析来发现它没有被使用。

将调试函数(包括它们的字符串文本)放入一个单独的翻译单元中,当您不希望它们显示时,不要与该TU链接。

附注。

如果启用调试,则行为未定义:

printf("%s",s);