【问题标题】:c++ force compiler to opt out some piece of codec ++强制编译器选择退出某些代码
【发布时间】:2013-05-04 05:29:12
【问题描述】:

我有一段代码:

// some code, which only do sanity check
expensive checks
// sanity check end

现在我如何告诉编译器强制它退出 这块?基本上这意味着当我使用 -O2 或 O3,我不希望它在那里……

谢谢!

【问题讨论】:

    标签: c++ optimization compiler-construction


    【解决方案1】:

    您可以使用一个常量和一个 if/def 对来完成此操作。这允许代码仍然被编译和检查错误,但在优化期间被忽略。这可以防止可能破坏检查代码的更改未被检测到。

    #if defined(USE_EXPENSIVE_CHECKS) || defined(DEBUG)
    #define USE_EXPENSIVE_CHECKS_VALUE true
    #else
    #define USE_EXPENSIVE_CHECKS_VALUE false
    #endif
    
    namespace {
     const bool useExpensiveChecks = USE_EXPENSIVE_CHECKS_VALUE;
    };
    
    void function()
    {
        if(useExpensiveChecks == true)
        {
            // expensive checks
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以仅在希望代码运行时向编译器传递额外的符号定义,而不是依赖编译器来优化代码:

      // some code, which only do sanity check
      #ifdef my_symbol
      expensive checks
      #endif
      // sanity check end
      

      【讨论】:

      • 嗯,有没有更好的方法来做到这一点?我知道我可以通过一些标志来控制它,但这真的不是我想要的
      • @WhatABeautifulWorld 你认为什么是“更好的方式”?
      • @WhatABeautifulWorld 所以你希望编译器读懂你的想法?显然,您必须指定一些东西来告诉编译器它应该做什么,并且在一个地方(makefile)这样做对我来说似乎非常接近最佳。
      【解决方案3】:

      在预处理器中使用宏和条件确实是避免编译器生成代码的唯一方法。

      所以,我会这样做:

      #ifdef NEED_EXPENSIVE_CHECKS
      inline expensive_checking(params...)
      {
         ... do expensive checking here ... 
      }
      #else
      inline expensive_checking(params...)
      {
      }
      #endif
      

      然后只需调用:

      some code
      expensive_checking(some_parameters...)
      some other code
      

      在任何体面的现代编译器中,空的内联函数都会导致“无代码”。在调试构建设置中使用-DNEED_EXPENSIVE_CHECKS,不要在发布构建中使用它。

      我还知道使用宏和函数的组合,例如:

      #ifdef NEED_EXPENSIVE_CHECKS
      #define EXPENSIVE_CHECKS(stuff...) expensive_checks(__FILE__, __LINE__, stuff...)
      inline expensive_checks(const char *file, int line, stuff ...)
      {
         if (some_checking)
         {
            cerr << "Error, some_checking failed at " << file << ":" << line << endl;
         }
      }
      #else
      #define EXPENSIVE_CHECKS(stuff...)
      #endif
      

      现在,您可以在出现故障时获得有关哪个文件和哪一行的信息,如果在许多地方进行检查,这将非常有用(您也可以使用__function____pretty_function__ 来获取函数名, 如果你希望)。

      很明显,assert() 宏基本上会做我的宏解决方案所做的,除了它通常不提供文件名和行号。

      【讨论】:

        【解决方案4】:

        将您的支票移动到不同的函数中,然后导入cassert 并写入assert(expensive_check())。当您想禁用检查时,请使用#define NDEBUG包含 cassert。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多