Igo*_*r G 6 c++ language-lawyer c++17
是否存在函数foo()和optimized_foo()下面示例中不等效的情况?
struct Test
{
int x;
int y;
int z;
};
// Some external function. Implementation unknown.
void bar(int& arg);
void foo()
{
Test t;
t.x = 3;
t.y = 4;
t.z = 5;
bar(t.y);
}
void optimized_foo()
{
int t_y = 4;
bar(t_y);
}
Run Code Online (Sandbox Code Playgroud)
只是所有主要的 x86_64 编译器(gcc 10.2、clang 10.0、msvc 19.24)都会在生成的汇编代码中保留初始化t.x和t.z在foo()最高优化级别生成的汇编代码。即使这些成员显然没有被使用。他们有理由吗?
我是否正确假设bar(),在获得对结构的一个数据成员的引用后,没有合法的方法来获取对其他成员的指针/引用?标准对此有何评论?
bar可以通过引用 [expr.unary.op] 获取成员的地址。然后该函数可以复制相邻成员的对象表示的字节。
void bar(int& arg) {
constexpr auto size = sizeof(Test);
constexpr auto offset = offsetof(Test, y);
constexpr auto remaining = size - offset;
unsigned char buffer[remaining];
std::memcpy(buffer, &arg, remaining);
}
Run Code Online (Sandbox Code Playgroud)
在函数的末尾,缓冲区包含对象的某些成员的Test对象表示。鉴于这bar是在外部定义的,编译器无法知道在编译时是否观察到其他成员的内存foo。
注意:offsetof仅对非标准布局类型有条件地支持。有问题的类是标准布局。
[基本类型]
对于任何可简单复制类型 T 的对象(除了潜在重叠的子对象),无论该对象是否持有 T 类型的有效值,构成该对象的底层字节([intro.memory])都可以复制到char、unsigned char 或 std?::?byte ([cstddef.syn]) 的数组。如果该数组的内容被复制回对象,则该对象随后将保持其原始值。
T 类型对象的对象表示是 T 类型对象占用的 N 个 unsigned char 对象的序列,其中 N 等于 sizeof(T)。...
PS 我使用了一个奇怪的例子,只观察连续的成员,因为观察前面的成员需要显式的指针运算,这在标准中有些含糊不清。我认为这样做没有实际问题,但我将其从示例中省略以将问题分开。见相关帖子。
| 归档时间: |
|
| 查看次数: |
111 次 |
| 最近记录: |