4

我正在寻找以下问题的答案:是否may_alias适合作为指向某个类对象的指针的属性Foo?还是只能在班级级别使用?

考虑以下代码(它基于更复杂的真实示例):

#include <iostream>

using namespace std;

#define alias_hack __attribute__((__may_alias__))

template <typename T>
class Foo
{
private:
    /*alias_hack*/ char Data[sizeof (T)];
public:
    /*alias_hack*/ T& GetT()
    {
        return *((/*alias_hack*/ T*)Data);
    } 
};

struct Bar
{
    int Baz;

    Bar(int baz)
      : Baz(baz)
    {}
} /*alias_hack*/; // <- uncommeting this line apparently solves the problem, but does so on class-level(rather than pointer-level)
// uncommenting previous alias_hack's doesn't help

int main()
{
    Foo<Bar> foo;
    foo.GetT().Baz = 42;
    cout << foo.GetT().Baz << endl;
}

有没有办法告诉 gcc 那个单指针may_alias另一个?

顺便说一句,请注意,此类问题的 gcc 检测机制是不完善的,因此很容易让这个警告消失而没有真正解决问题。

考虑以下代码片段:

#include <iostream>

using namespace std;

int main()
{
    long i = 42;
    long* iptr = &i;
    //(*(short*)&i) = 3; // with warning
    //(*(short*)iptr) = 3; // without warning
    cout << i << endl;
}

取消注释其中一行以查看编译器输出的差异。

4

2 回答 2

2

简单的回答——对不起,不。

__attrbit__ 向编译器提供指令。对象存在于执行程序的内存中。因此 __attribute__ 列表中的任何内容都与运行时执行无关。

于 2013-05-08T04:47:16.873 回答
1

迪米塔尔是正确的。may_alias 是一个类型属性。它只能应用于一个类型,而不是该类型的一个实例。您想要的是 gcc 所说的“变量属性”。禁用一个特定指针的优化并不容易。如果你用这个指针调用一个函数,编译器会做什么?该函数可能已经编译,并将根据传递给函数的类型运行,而不是基于指针中的地址存储(您现在应该明白为什么这是一个类型属性)

现在取决于您的代码,类似的东西可能会起作用:

#define define_may_alias_type(X) class X ## _may alias : public X { } attribute ((may_alias));

当它可能别名时,您只需将指针作为Foo_may_alias *(而不是)传递。Foo *虽然这很hacky

写你关于警告的问题,这是因为-Wall默认值-Wstrict-aliasing=3不是 100% 准确的。实际上,-Wstrict-aliasing永远不会 100% 准确,但取决于级别,您会或多或少地得到假阴性(和假阳性)。如果你传递-Wstrict-aliasing=1给 gcc,你会看到一个警告

于 2013-05-08T16:27:29.003 回答