代码之家  ›  专栏  ›  技术社区  ›  Rob

将宏转换为内联函数

c++
  •  3
  • Rob  · 技术社区  · 14 年前

    #define VERIFY(cond) \
    { \
        bool ok = cond; \
        Q_ASSERT(ok); \
    }
    

    Q_ASSERT(callSomeFunction()); // callSomeFunction not evaluated in release builds!
    VERIFY(callSomeFunction());   // callSomeFunction is always evaluated
    

    我不喜欢宏,而是想把它变成一个内联函数:

    inline VERIFY(bool condition)
    {
      Q_ASSERT(condition);
    }
    

    Q_ASSERT

    inline VERIFY(bool condition)
    {
      condition;
      Q_ASSERT(condition);
    }
    

    但是,同样,编译器可能足够聪明,可以忽略调用。

    这个内联替代方案对调试和发布版本都安全吗?

    4 回复  |  直到 14 年前
        1
  •  2
  •   sharptooth    14 年前

    因为它们的评估可能有副作用,也可能没有副作用,所以在维护代码的过程中,充其量会有困难——在有副作用的情况下,评估肯定会发生,在其他情况下,它的发生与否由编译器决定。这就给您留下了一个以松散控制方式运行的程序。

    所以即使你不喜欢宏,你也应该做出明智的决定。要么使用宏,然后预处理器消除整个构造,而不计算参数;要么使用内联函数,然后编译器为您决定。

        2
  •  4
  •   Troubadour    14 年前

    即使编译器优化了内联VERIFY函数,也不意味着它不会调用生成bool参数的函数。

    qu ASSERT不调用在发布版本中传递给它的函数的原因是,它是一个宏,根本不能代替函数调用,因此没有什么可以优化的。

        3
  •  0
  •   AshleysBrain    14 年前

    想象一下这个代码:

    int x = Return5();
    int y = PrintToConsoleAndReturn5();
    
    // x and y never used again
    

    乐观主义者可以忽略对 Return5() (假设它只是由 return 5; PrintToConsoleAndReturn5() y ,因为该代码没有副作用。简言之,理论是程序的行为应该是相同的,无论是优化还是非优化,所以你应该在你原来的问题。

        4
  •  0
  •   MSalters    14 年前

    在优化过程中,编译器仍然必须尊重手头代码的可观察效果。这意味着它必须保持 callSomeFunction() 如果这是可以观察到的(有一些特殊的例外情况适用于复制周围的对象,在这些情况下,可以注意到复制的消除(这里不相关)。

    然而,优化对你来说并不重要 Q_ASSERT(callSomeFunction());