根据项目的调试/发布状态,两次定义琐碎的内联方法是否有用?

nha*_*123 0 c++ optimization class-design

我一直想知道,如果两次定义琐碎方法是好的还是坏的做法,这取决于
项目是在debug/release -state上.这是为了内联它们.例如,Foo.h:


class Foo
{
        public:
                ...

                const bool& IsBoolean() const;

        private:
                bool _boolean;
};

#ifndef _DEBUG

/** We're in release, so let's advice compiler to inline this...
  *
  *
  */

inline const bool& Foo::IsBoolean() const
{
        return _boolean;
}

#endif

Run Code Online (Sandbox Code Playgroud)

现在,在Foo.cpp中:


#include "Foo.h"

...

#ifdef _DEBUG

/** We're debugging this, no need for inlining...
  *
  *
  */

const bool& Foo::IsBoolean() const
{
        return _boolean;
}

#endif
Run Code Online (Sandbox Code Playgroud)

这完全没用吗?例如,由于编译器(MSVC)能够自行内联/优化方法?

然而,这是我多年来一直使用的东西.请纠正我,如果我在这里完全错了......

jal*_*alf 9

由于几个原因,这是浪费时间.

inline关键字是编译器可以随意忽略的提示.就像它可以自由内联,即使没有指定关键字.因此,无论您是否添加它可能不会改变编译器的任何内容

此外,类定义中定义的任何函数都是隐式内联的.这就是为什么像getter和setter这样的短函数几乎总是在类定义中定义的原因.

接下来,如果要将函数标记为内联,则没有理由不在调试版本中执行此操作.

inline关键字几乎与编译器实际内联函数无关.它们是不同的概念.inline程序员标记的函数意味着链接器在看到多个相同的定义时不应该担心.如果函数在头文件中定义,则通常会发生这种情况,该头文件包含在多个编译单元中.如果函数标记为内联,则链接器将定义合并在一起.如果不是,则会出错.换句话说,添加和删除此关键字将导致编译器错误.这可能不是你想要的.

C++ inline关键字和编译器优化之间存在一些重叠的唯一原因是,如果标记了一个函数inline,则在每个编译单元中#include它是安全的,这意味着在调用函数时该定义将始终可见.这使得编译器可以更容易地内联对函数的调用.

最后,内联并不总是性能提升.很容易创建一种情况,其中内联只会使代码大小爆炸,导致更多的缓存未命中,总体而言,会降低代码速度.这就是为什么inline(充其量)被优化器视为提示的原因之一.在最坏的情况下,它完全被忽略.

所以你正在做的将是1)导致在发布版本中不存在的调试模式中的编译器错误,以及2)对性能没有影响.