当前位置: 首页 > 知识库问答 >
问题:

是什么阻止编译器消除每个特定上下文中未使用的数据成员?

上官琦
2023-03-14

下面示例中的函数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);
}

只是所有主要的x86_64编译器(gcc 10.2,clang 10.0,msvc 19.24)在为foo()生成的汇编代码中保留了t. xt. z的初始化,即使在最高优化级别。即使那些成员显然没有被使用。他们有原因吗?

假设< code>bar()被给定了一个对结构中一个数据成员的引用,却没有合法的方法获得对其他成员的指针/引用,我说的对吗?标准是怎么说的?

共有1个答案

宇文育
2023-03-14

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);
}

在函数的末尾,缓冲区包含 Test 对象的某些成员的对象表示形式。鉴于 bar 是在外部定义的,编译器无法知道在编译 foo 时是否观察到其他成员的内存。

注意:offsetof仅有条件地支持非标准布局类型。有问题的类是标准布局。

[基本类型]

对于可简单复制类型 T 的任何对象(潜在重叠子对象除外),无论该对象是否持有 T 类型的有效值,构成该对象的基础字节 ([intro.memory]) 都可以复制到字符、无符号字符或 std::byte ([cstddef.syn] ) 数组中。如果该数组的内容被复制回对象,则该对象随后应保持其原始值。

类型T的对象的对象表示是由类型T的对象占用的N个无符号char对象的序列,其中N等于sizeof(T)。...

另外,我用了一个奇怪的例子,只观察连续的成员,因为观察前面的成员需要显式的指针算法,这在标准中有点含糊不清。我认为这样做没有什么实际问题,但为了将问题分开,我在示例中省略了它。参见相关帖子。

 类似资料:
  • 问题内容: Python代码对象具有属性。PyPy字节码解释器的文档通常使用术语 Cell 。 在其他语言中,Rust提供了Cell数据类型。谷歌搜索表明它们以某种方式与闭包相关。 在编程语言实现的上下文中,什么是 单元 ?细胞能解决什么问题? 问题答案: 在Python中,对象是用于存储自由变量一个的关闭。 假设您想要一个始终返回其参数的特定部分的函数。您可以使用闭包来实现此目的: 这是如何使用

  • 主要内容:什么是编译器,什么是集成开发环境,选择哪种集成开发环境我们平时所说的程序,是指双击后就可以直接运行的程序,这样的程序被称为 可执行程序(Executable Program)。在 Windows 下,可执行程序的后缀有 .exe 和 .com(其中 .exe 比较常见);在类 UNIX 系统(Linux、Mac OS 等)下,可执行程序没有特定的后缀,系统根据文件的头部信息来判断是否是可执行程序。 可执行程序的内部是一系列计算机指令和数据的集合,它们

  • 本文向大家介绍什么是ElasticSearch中的编译器?相关面试题,主要包含被问及什么是ElasticSearch中的编译器?时的应答技巧和注意事项,需要的朋友参考一下 编译器用于将字符串分解为术语或标记流。一个简单的编译器可能会将字符串拆分为任何遇到空格或标点的地方。Elasticsearch有许多内置标记器,可用于构建自定义分析器。

  • 我是Intellij的新手。覆盖每个模块的编译器参数的含义是什么?如果我删除参数会发生什么?更多细节的屏幕快照。

  • UE4 的底层虽然是用 C++ 实现的,但它又不仅仅是一个 C++ 库,它还实现了自己的编译机制。换句话说,UE4 对现有的 C++ 语法进行了改进,以适应游戏开发的场景。 当然,UE4 也不会疯狂到自己去开发一个 C++ 编译器,它还是需要依赖传统的 C++ 编译器以及相关的编程套件。 熟悉 Qt 的读者应该知道,Qt 虽然也使用 C++,但是它还提供了信号和槽的机制,这是原生 C++ 里面没有