4

我收到这个警告。我想要定义的行为,但我想保持此代码不变。我什么时候可以打破别名规则?

警告:取消引用类型双关指针将破坏严格别名规则 [-Wstrict-aliasing]

字符串是我自己的字符串,它是一个 POD。这段代码是从 C 调用的。S 可能是一个 int。字符串几乎是struct String { RealString*s; }模板化和辅助函数。我做了一个静态断言来确保 String 是一个 pod,是 4bytes 并且 int 是 4bytes。我还写了一个断言来检查所有指针是否>= NotAPtr。它在我的 new/malloc 重载中。如果您建议,我也可以将该断言放入 String

考虑到我遵循的规则(主要是字符串是一个 pod 并且始终与 int 大小相同)如果我打破别名规则会很好吗?这是少数几次打破它的人之一吗?

void func(String s) {
    auto v=*(unsigned int*)&s;
    myassert(v);
    if(v < NotAPtr) {
        //v is an int
    }
    else{
        //v is a ptr
    }
}
4

4 回答 4

4

memcpy完全支持。双关语也是如此char*(例如,您可以使用std::copy)。

于 2012-06-09T23:46:59.410 回答
1

如果您不能按照建议将代码更改为 2 个函数,为什么不(需要 C99 编译器作为使用uintptr_t- 对于较旧的 MSVC,您需要自己定义它,2008/2010 应该可以):

void f(RealString *s) {
    uintptr_t int = reinterpret_cast<uintptr_t>(s);
    assert(int);
}
于 2012-06-09T23:25:53.447 回答
1

该标准指定了所有符合要求的实现必须以可预测的方式处理的最小操作集,除非它们遇到翻译限制(因此所有赌注都关闭)。它并不试图定义实现必须支持以适用于任何特定目的的所有操作。相反,对超出授权范围的行动的支持被视为实施质量问题。作者承认,一个实现可能是合规的,但质量却很差,以至于毫无用处。

像您这样的代码应该可用于旨在用于低级编程的高质量实现,并以预期的方式表示内存中的事物。不应期望它可用于其他类型的实现,包括那些将“实现质量”问题解释为试图以低质量但符合标准的方式行事的邀请。

于 2018-07-13T19:42:48.567 回答
-2

将变量视为两种不同类型的安全方法是将其转换为联合。联合的一部分可以是您的指针,另一部分是整数。

struct String
{
    union
    {
        RealString*s;
        int i;
    };
};
于 2012-03-19T19:35:26.370 回答