c++ - C++ 中的严格别名规则和类型别名

标签 c++ language-lawyer strict-aliasing type-punning

我试图在违反严格的别名规则时了解未定义的行为。为了理解它,我阅读了很多关于 SO 的文章。然而,一个问题仍然存在:我真的不明白两种类型的别名是非法的。 cpp-reference状态:

Type aliasing

Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true:

  • AliasedType and DynamicType are similar.
  • AliasedType is the (possibly cv-qualified) signed or unsigned variant of DynamicType.
  • AliasedType is std::byte, (since C++17)char, or unsigned char: this permits examination of the object representation of any object as an array of bytes.

我还找到了一个 nice example on SO我清楚地看到问题的地方:

int foo( float *f, int *i ) { 
    *i = 1;               
    *f = 0.f;            

   return *i;
}

int main() {
    int x = 0;

    std::cout << x << "\n";   // Expect 0
    x = foo(reinterpret_cast<float*>(&x), &x);
    std::cout << x << "\n";   // Expect 0?
}

intfloat 是不相似的类型,这个程序可能会造成严重破坏。我没有看到和理解的是以下修改:

struct A
{
    int a;
};

struct B
{
    int b;
};

A foo( A *a, B *b ) { 
    a->a = 1;               
    b->b = 0;            

    return *a;
}

int main() {
    A a;
    a.a = 0;


    std::cout << a.a << "\n";   // Expect 0
    a = foo(&a, reinterpret_cast<B*>(&a));
    std::cout << a.a << "\n";   // Expect 0?
}

AB 是相似的类型并且一切都很好,或者它们是非法别名并且我有未定义的行为。如果它是合法的,这是因为 AB 是聚合(如果是的话,我需要更改什么才能使其成为未定义的行为)?

任何提示和帮助将不胜感激。

编辑 关于重复的问题

我知道 this发布,但我看不到他们在哪里澄清哪些类型是相似的。至少没有达到我能理解的程度。因此,如果您不关闭此问题,我们将不胜感激。

最佳答案

不,这是不合法的,你有未定义的行为:

8.2.1 Value category [basic.lval]

11 If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined: 63

(11.1) — the dynamic type of the object,

(11.2) — a cv-qualified version of the dynamic type of the object,

(11.3) — a type similar (as defined in 7.5) to the dynamic type of the object,

(11.4) — a type that is the signed or unsigned type corresponding to the dynamic type of the object,

(11.5) — a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,

(11.6) — an aggregate or union type that includes one of the aforementioned types among its elements or nonstatic data members (including, recursively, an element or non-static data member of a subaggregate or contained union),

(11.7) — a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,

(11.8) — a char, unsigned char, or std::byte type


63) The intent of this list is to specify those circumstances in which an object may or may not be aliased.

关于c++ - C++ 中的严格别名规则和类型别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51984540/

相关文章:

c++ - 如何在 OpenGL 中捕捉准确的帧率

c++ - OpenCV 和 C++ : Error with Traincascade: A Practical Issue

c++ - union 的析构函数可以是微不足道的吗?

c++ - 在 C++ 中放置派生的新基子对象

c++ - 如何在 C++ 类中将所有私有(private) vector 换成私有(private)映射?

c++ - 意外的 DO-WHILE 行为 : Is it ignoring the expression?

c++ - 为什么这个指针为空

c++ - 如果从未通过它们进行修改,是否允许对实际 const 对象的引用进行 const 转换?

C++ 类型别名,其中值被替换

c - 我是否通过创建虚拟结构数据类型违反了严格的别名规则?