C++ 根据项目的调试/发布状态定义两次简单的内联方法有什么好处吗?

C++ 根据项目的调试/发布状态定义两次简单的内联方法有什么好处吗?,c++,optimization,class-design,C++,Optimization,Class Design,我一直在想,根据具体情况,两次定义一个简单的方法是好是坏 如果项目处于调试/发布状态。这是用于内联它们的。例如,Foo.h: class Foo { public: ... const bool& IsBoolean() const; private: bool _boolean; }; #ifndef _DEBUG /** We're in release,

我一直在想,根据具体情况,两次定义一个简单的方法是好是坏
如果项目处于调试/发布状态。这是用于内联它们的。例如,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

现在,在Foo.cpp中:


#include "Foo.h"

...

#ifdef _DEBUG

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

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

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


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

重复是不好的。即使您处理的是一个死气沉沉的编译器,您也可以很容易地避免这种重复,最坏的情况是,使用一个在一个位置定义的宏
INLINE
INLINE
,或者什么都不做。

看起来像是浪费空间和不必要的代码重复。通常,编译器能够自行确定哪些函数要内联,哪些函数不内联。如果您使用的是具有
/LTCG
(链接时间代码生成)的MSVC,则更是如此开关,这意味着即使在cpp中,您的琐碎方法也将内联。

最简单的方法是将代码放入自己的文件filename.inl中,然后有条件地将该文件包含在头文件或源文件中。您还应该在.inl文件中的函数前面加一个条件宏,如果文件包含在头文件中,该宏将扩展为内联,否则将扩展为空宏。

这是浪费时间,原因有几个

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

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

接下来,如果您想将函数标记为内联函数,那么没有理由不在调试构建中也这样做

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

<> P> > C++ >代码>内联< /COD>关键字和编译器优化之间的一点重叠的唯一原因是,如果函数被标记为“代码>内联”,则将其包含在每个编译单元中是安全的,这意味着在调用函数时,该定义将始终可见。这使得编译器很容易内联调用函数

最后,内联并不总是一种性能改进。很容易创建这样一种情况:内联只会导致代码大小爆炸,导致更多缓存未命中,并且总体上会降低代码的速度。这就是为什么优化器(最多)将
inline
视为提示的原因之一。最坏的情况是,它被完全忽略


因此,您所做的操作将1)在调试模式下导致编译器错误,而这在发布版本中是不存在的,2)对性能没有影响。

公平地说,您已经很好地解释了这一点。唉,这意味着一个巨大的代码清理:(但是,谢谢!嗯,删除大量重复代码并不是最糟糕的清理形式,至少是这样的。)