以下内联函数是否保证具有相同的实现

Are the following inlined functions guaranteed to have the same implementation?

本文关键字:实现 函数 是否      更新时间:2023-10-16
  • 以下函数是否保证具有相同的实现(即目标代码)
  • 如果下面的Foo是基元类型(例如int),这种情况会改变吗
  • 这会随着Foo的大小而改变吗

按价值返回:

inline Foo getMyFooValue() { return myFoo; }
Foo foo = getMyFooValue();

参照退货:

inline const Foo &getMyFooReference() { return myFoo; }
Foo foo = getMyFooReference();

修改到位:

inline void getMyFooInPlace(Foo &theirFoo) { theirFoo = myFoo; }
Foo foo;
getMyFooInPlace(foo);

以下函数是否保证具有相同的实现(即目标代码)?

不,该语言只指定行为,而不指定代码生成,因此两段具有等效行为的代码是否生成相同的目标代码取决于编译器。

如果下面的Foo是基元类型(例如int),这种情况会改变吗?

如果它是(或者,更普遍地说,如果它是平凡的可复制),那么这三者都有相同的行为,因此可以预期产生类似的代码。

如果它是一个非平凡的类类型,那么它取决于类的特殊函数的作用

  • 第一种可能复制初始化一个临时对象(调用复制构造函数),用它复制初始化foo,然后销毁临时对象(使用析构函数);但更有可能的是,它会消除暂时的,变得相当于第二个
  • 第二个将复制初始化foo(调用复制构造函数)
  • 第三个将默认初始化foo(调用默认构造函数),然后将assign复制到它(调用赋值运算符)

因此,它们是否等效取决于默认初始化和复制分配是否具有与复制初始化等效的行为,以及(也许)创建和销毁临时是否有副作用。如果它们是等价的,那么您可能会得到类似的代码。

这会随着Foo的大小而改变吗?

不,大小无关紧要。重要的是它是琐碎的(这样副本初始化和副本分配都只复制字节)还是非琐碎的(所以它们调用用户定义的函数,它们可能等价,也可能不等价)。

标准草案N3337在1.9.5中包含以下规则:"一致的[C++]实现[…]应产生与使用相同程序和相同输入的抽象机的相应实例的可能执行之一相同的可观察行为。"在1.9.9中,它将可观察行为基本定义为I/O和volatile的值。这意味着,只要程序的I/O和波动保持不变,实现就可以随心所欲。如果您没有I/O或挥发物,程序就不需要做任何事情(这使得使用高优化很难正确执行基准测试)。

请注意,该标准对编译器应该发出的代码完全没有说明。见鬼,它可能解释来源。

这回答了您的问题:不。