Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用内联方式分离源和头是否有效?_C++_Gcc - Fatal编程技术网

C++ 使用内联方式分离源和头是否有效?

C++ 使用内联方式分离源和头是否有效?,c++,gcc,C++,Gcc,我被告知编译器忽略内联或\uu内联关键字,除非另有说明,如VS 所以我想写这样的代码: class A { public: inline A() { P(); //yep, works } inline void P() { } } //.h class A { public: A(); void P(); } //.cpp #include ".h" A::A() { P(); } void A::P() { }

我被告知编译器忽略
内联
\uu内联
关键字,除非另有说明,如VS

所以我想写这样的代码:

class A {
public:
    inline A() {
         P(); //yep, works
    }
    inline void P() {
    }
}
//.h
class A {
public:
    A();
    void P();
}

//.cpp
#include ".h"
A::A() {
    P();
}
void A::P() {
}
而不是像这样分开它:

class A {
public:
    inline A() {
         P(); //yep, works
    }
    inline void P() {
    }
}
//.h
class A {
public:
    A();
    void P();
}

//.cpp
#include ".h"
A::A() {
    P();
}
void A::P() {
}
出于对C#的纯粹的懒惰和爱


所以问题是:即使在每种现有情况下,它们在优化方面是否同样有效?除了内联不再为真的函数外,内联关键字没有其他作用?

编译器可以选择忽略
内联

这并不意味着它完全忽略了
内联
,它只是把它当作一个提示

当你把所有的东西都像这样在线时,你很可能会得到一个更大的编译文件,因为会有比通常更多的在线文件


你也用C++编写,而不是C语言,所以纯C的懒惰和爱不是编写坏C++代码的借口。如果它的方法定义和调用方在不同的编译单元(.CPP文件),则

GCC不能内联方法。因此,您需要将定义放在标题中

如果启用了链接时间代码生成,VisualStudio可能会将其内联,默认情况下使用/O3

在这两种情况下,注意到“内联”关键字在C++中的含义与C相比有了改变。它现在具有语义意义,而不是内联提示。

您可以在VisualStudio中使用_forceinline来强制内联-实际上,它可以在语义上可能的所有情况下工作


对于GCC,您可以使用属性((总是内联的)),但GCC并不总是遵守它-它仍然会影响代码大小(不像Visual Studio总是遵守它)。

您的问题中有一些误解:

  • inline
    实际上有一个与优化无关的效果:它允许多个定义(这样您就可以将一个内联定义放在包含在多个编译单元中的头中)
  • 当您定义方法“inline”(更广泛地说是在类声明中写下它)时,它也隐式地是关键字意义上的
    inline
    。因此,在这些定义上编写关键字是毫无意义的

至于性能:实际上是有区别的,因为在第一种情况下,定义在包含头文件的编译单元中是可见的(因此方法可以内联),而在后一种情况下(假设没有链接时间优化),定义是不可见的,不能内联或以其他方式分析。这是一个相当小的优点:虽然大多数C和C++代码都是很好的,留下了99%个“非内联”函数。此外,还有一些缺点(代码膨胀、icache压力、编译时间增加),所以不要以此为理由在头文件中编写方法定义。在实现文件中写入它,只输出声明是C++中的标准方法,并且具有C经验并不是偏离这个标准的一个很好的理由。

< P>是的,编译器可能会选择忽略<代码>内联< /C> >,但是有一个很好的理由:内联可以显著地降低程序的速度。内联意味着更大的代码大小,这意味着CPU的指令缓存压力更大,这意味着性能更低。编译器编写人员知道这一点,因此有一些启发式方法,可以遵循
inline
提示,也可以不遵循

虽然你可以把所有的东西都放在C++中的头文件中,但是这样做不是一个好主意:

  • 即使这样也不会强制内联。编译器仍必须在对象文件中发出函数,链接器的任务是丢弃副本。在编译时间方面,您为此付出了代价,但得到的回报很少

  • 当您更改.cpp文件中的代码时,只需重新编译该文件;更改标头时,必须重新编译所有从属文件。如果所有内容都在一个标题中,那么您必须始终将程序构建为一个大的整体块。对于大型项目,这大大降低了测试更改构建周期的频率,从而大大降低了生产效率


  • 我强烈建议您接受C/C++中头文件和实现文件之间的区别,这确实节省了大量时间。

    我不确定它是如何回答这个问题的;我想你误解了什么。GCC还支持使用-flto进行链接时间优化。如果方法很短,并且参数数量很大,那么内联它将具有非常高的性能benefit@LasseReinhold这到底有多普遍?我真的不明白你的意思。我非常清楚内联是一种强大的优化,我没有写过相反的东西。但这不是一个自动的胜利,所以它的使用必须有针对性和正当性。