首页 文章

当CAN我打破别名规则?

提问于
浏览
4

我收到了这个警告 . 我想定义行为,但我想保持这个代码的原样 . 什么时候可以打破别名规则?

警告:解除引用类型惩罚指针将破坏严格别名规则[-Wstrict-aliasing]

String是我自己的字符串,它是一个POD . 此代码从C调用.S可能是int . 字符串几乎是 struct String { RealString*s; } 但是模板和辅助函数 . 我做一个静态断言来确保String是一个pod,是4bytes,int是4bytes . 我还写了一个断言,检查所有指针是否> = NotAPtr . 它在我的新/ 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 回答

  • 1

    完全支持 memcpy . 所以是对 char* 的惩罚(例如,你可以使用 std::copy ) .

  • 1

    如果您不能将代码更改为2个函数,那么为什么不呢(要求C99编译器使用 uintptr_t - 对于较旧的MSVC,您需要自己定义,2008/2010应该没问题):

    void f(RealString *s) {
        uintptr_t int = reinterpret_cast<uintptr_t>(s);
        assert(int);
    }
    
  • 4

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

    struct String
    {
        union
        {
            RealString*s;
            int i;
        };
    };
    
  • -2

    标准规定了一组最小的操作,所有符合要求的实现必须以可预测的方式处理,除非它们遇到转换限制(因此所有的投注都是关闭的) . 它不会尝试定义实现必须支持的所有操作以适合任何特定目的 . 相反,对超出这些授权的行动的支持被视为执行质量问题 . 作者承认,实施可能符合要求,但质量很差,无用 .

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

相关问题