【问题标题】:Aliasing signed and unsigned integers during optimization在优化期间对有符号和无符号整数进行别名
【发布时间】:2022-11-11 01:06:26
【问题描述】:

signed& 不能从 unsigned& 初始化(反之亦然),但严格的别名规则允许通过 unsigned& 读取/写入 signed 对象(反之亦然),请参阅 C++20 标准 @ 987654321@。如果不违反as-if rule,这理论上可以用于编译器优化。

示例 1。如果我是正确的,f 可以通过跳转到foo 来实现:

void foo(const unsigned&);

void f(const signed& par)
{
    foo(par);
}

但是所有编译器都将par 加载到寄存器中,将寄存器存储在堆栈中,并将堆栈位置传递给fooLive demo

示例 2。同样,我认为g1g2 可以指向相同的内存位置:

const signed&   g1 = 1;
const unsigned& g2 = g1;

但是编译器倾向于分配两个不同的位置。 Live demo

问题。这是为什么?这不是错过了优化的机会吗?

【问题讨论】:

    标签: c++ compiler-optimization strict-aliasing as-if


    【解决方案1】:
    const signed&   g1 = 1;
    const unsigned& g2 = g1;
    

    但是编译器倾向于分配两个不同的位置。

    在这里,发生的事情是g1 被转换为临时unsigned int 并且g2 绑定到这个临时。而C++保证不同的对象有不同的地址,因此g1g2需要不同的存储。

    与您的函数示例相同。从技术上讲,这些函数可以依赖于它们的参数地址不相同的事实。

    【讨论】:

    • @Dr.Gut 当且仅当用户无法检测到某些不同时,as-if 规则才适用。在这里,用户能够通过检查地址来检测它,所以它是不是适用的。
    • @Dr.Gut Strict 别名豁免意味着您可以使用unsigned 指针指向int你自己.这并不意味着允许编译器合并不相关的对象,因为那样你就没有唯一的地址,这是由语言保证的。
    • @Dr.Gut 见The as-if rule“允许任何和所有代码转换不会改变程序的可观察行为。".
    • 您的论点对全局变量有意义,但对函数没有意义。您是说同时运行的同一函数调用的两个实例(例如在不同的线程中)必须能够比较它们的函数参数的地址并发现它们不同,因为它们是不同类型的引用,因为源没有t 做任何类型的双关语所以必须制作副本?或者您的意思是将&par&g2 或其他东西进行比较并保证发现它不同?
    • @PeterCordes 考虑this。 6号线一定不失败,因为这些是不同的对象。如果函数参数被“优化”为相同的内存,它将失败。
    猜你喜欢
    • 2011-08-10
    • 1970-01-01
    • 2013-10-02
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    相关资源
    最近更新 更多