类型 - 双关语(GCC) - 在堆栈上递增指针参数

时间:2015-02-09 18:58:21

标签: pointers gcc casting

好的,我知道GCC 4.x警告"解除引用类型惩罚指针将破坏严格别名规则"不是开玩笑,我应该清理我的代码。

我有代码编译和GCC 3.x运行良好,如果它也会用GCC 4.x这样做会非常高兴。假设我想让汇编的代码尽可能短:函数传递一个指针,并应该向那里写入一些数据。我的原始代码直接在堆栈上使用指针(没有副本)并在那里递增(注意我不想将递增的值传递回调用者)。您也可以考虑通过寄存器传递参数 - 然后任何副本都是开销。

所以这是我的理想"代码:

void foo(void *pdataout) {
    for (int i=16; i--;)
        *(*reinterpret_cast<BYTE**>(&pdataout))++ = 255;
}

我尝试了一些变体(请注意,在任何类型转换之前,地址运算符必须应用于&#39; pdataout&#39;)

void foo(void *pdataout) {
    BYTE *pdo = reinterpret_cast<BYTE*>(*reinterpret_cast<BYTE**>(&pdataout));

    for (int i=16; i--;)
        *pdo++ = 255;
}

还有这个:

void foo(void *pdataout) {
    BYTE *pdo = *reinterpret_cast<BYTE**>(&pdataout);

    for (int i=16; i--;)
        *pdo++ = 255;
}

GCC 4.x没有什么可取的...这最后一个可以 - 但是,它使用了我不喜欢的参数副本。没有副本有没有办法做到这一点?我不知道怎么告诉编译器: - (

void foo(void *pdataout) {
    BYTE *pdo = reinterpret_cast<BYTE*>(pdataout);

    for (int i=16; i--;)
        *pdo++ = 255;
}

1 个答案:

答案 0 :(得分:0)

据我所知,尽管GCC不再发出警告,但通过附加变量使用间接是不安全的!

对我来说(由于union不可用),唯一真正的解决方案是使用-fno-strict-aliasing编译器选项。只有这样,GCC才知道不同类型的指针到同一个内存地址可以引用相同的变量。

This article终于帮助我理解了严格别名。