以下内联函数是否保证具有相同的实现?
Are the following inlined functions guaranteed to have the same implementation?
- 是否保证以下函数具有相同的实现(即目标代码)?
- 如果下面的
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);
标准草案 N3337 在 1.9.5 中包含以下规则:"A conforming [C++] implementation [...] shall produce the same observable behaviour as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input." 在 1.9.9 中,它基本上将可观察行为定义为 I/O 和 volatile 的值。这意味着只要程序的 I/O 和 volatiles 保持不变,实现就可以做它想做的事。如果你没有 I/O 或 volatiles 程序不需要做任何事情(这使得基准测试很难通过高度优化获得正确)。
请注意,该标准对编译器应发出的代码完全没有提及。该死,它可能 解释 来源。
这回答了你的问题:否。
Are the following functions guaranteed to have the same implementation (i.e. object code)?
不,语言只指定行为,不指定代码生成,因此由编译器决定具有相同行为的两段代码是否产生相同的目标代码。
Does this change if Foo
below is a primitive type instead (e.g. int
)?
如果是(或者,更一般地说,如果它是可简单复制),那么所有三个都具有相同的行为,因此可以预期生成相似的代码。
如果它是一个重要的 class 类型,那么它取决于 class 的特殊函数的作用。每个调用这些函数的方式略有不同:
- 第一个可能复制初始化一个临时对象(调用复制构造函数),复制初始化
foo
,然后销毁临时对象(调用析构函数);但更有可能它会省略临时的,变得等同于第二个。
- 第二个将复制初始化
foo
(调用复制构造函数)
- 第三个将默认初始化
foo
(调用默认构造函数),然后复制赋值给它(调用赋值运算符)。
所以它们是否等效取决于默认初始化和复制赋值是否具有与复制初始化等效的行为,以及(可能)创建和销毁临时对象是否有副作用。如果它们是等价的,那么您可能会得到类似的代码。
Does this change with the size of Foo
?
不,尺寸无关紧要。重要的是它是微不足道的(这样复制初始化和复制赋值都只是复制字节)还是非微不足道的(这样它们调用用户定义的函数,它们可能等价也可能不等价)。
- 是否保证以下函数具有相同的实现(即目标代码)?
- 如果下面的
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);
标准草案 N3337 在 1.9.5 中包含以下规则:"A conforming [C++] implementation [...] shall produce the same observable behaviour as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input." 在 1.9.9 中,它基本上将可观察行为定义为 I/O 和 volatile 的值。这意味着只要程序的 I/O 和 volatiles 保持不变,实现就可以做它想做的事。如果你没有 I/O 或 volatiles 程序不需要做任何事情(这使得基准测试很难通过高度优化获得正确)。
请注意,该标准对编译器应发出的代码完全没有提及。该死,它可能 解释 来源。
这回答了你的问题:否。
Are the following functions guaranteed to have the same implementation (i.e. object code)?
不,语言只指定行为,不指定代码生成,因此由编译器决定具有相同行为的两段代码是否产生相同的目标代码。
Does this change if
Foo
below is a primitive type instead (e.g.int
)?
如果是(或者,更一般地说,如果它是可简单复制),那么所有三个都具有相同的行为,因此可以预期生成相似的代码。
如果它是一个重要的 class 类型,那么它取决于 class 的特殊函数的作用。每个调用这些函数的方式略有不同:
- 第一个可能复制初始化一个临时对象(调用复制构造函数),复制初始化
foo
,然后销毁临时对象(调用析构函数);但更有可能它会省略临时的,变得等同于第二个。 - 第二个将复制初始化
foo
(调用复制构造函数) - 第三个将默认初始化
foo
(调用默认构造函数),然后复制赋值给它(调用赋值运算符)。
所以它们是否等效取决于默认初始化和复制赋值是否具有与复制初始化等效的行为,以及(可能)创建和销毁临时对象是否有副作用。如果它们是等价的,那么您可能会得到类似的代码。
Does this change with the size of
Foo
?
不,尺寸无关紧要。重要的是它是微不足道的(这样复制初始化和复制赋值都只是复制字节)还是非微不足道的(这样它们调用用户定义的函数,它们可能等价也可能不等价)。