1
  • 以下函数是否保证具有相同的实现(即目标代码)?
  • 如果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);
4

2 回答 2

1

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

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

如果Foo下面是原始类型(例如int),这会改变吗?

如果是(或者,更一般地说,如果它是可简单复制的),那么这三个都具有相同的行为,因此可以预期会产生类似的代码。

如果它是一个非平凡的类类型,那么它取决于类的特殊功能做什么。每个调用这些函数的方式略有不同:

  • 第一个可能复制初始化一个临时对象(调用复制构造函数),复制初始化foo,然后销毁临时对象(调用析构函数);但更有可能的是它会忽略暂时的,变得等同于第二个。
  • 第二个将复制初始化foo(调用复制构造函数)
  • 第三个将默认初始化foo(调用默认构造函数),然后复制分配给它(调用赋值运算符)。

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

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

不,大小无关紧要。重要的是它是微不足道的(因此复制初始化和复制分配都只是复制字节)还是非平凡的(以便它们调用用户定义的函数,它们可能彼此等效,也可能不等效)。

于 2015-02-19T11:37:02.057 回答
0

标准草案 N3337 在 1.9.5 中包含以下规则:“符合标准的 [C++] 实现 [...] 应产生与具有相同程序的抽象机器的相应实例的可能执行之一相同的可观察行为,并且相同的输入。” 而在 1.9.9 中,它基本上将可观察行为定义为 I/O 和 volatile 的值。这意味着只要程序的 I/O 和 volatile 保持不变,实现就可以做它想做的事。如果您没有 I/O 或 volatile,则程序不需要做任何事情(这使得基准测试很难通过高度优化得到正确)。

请注意,该标准完全没有说明编译器应该发出什么代码。地狱,它可能可以解释来源。

这回答了你的问题:不。

于 2015-02-19T11:35:22.397 回答