代码之家  ›  专栏  ›  技术社区  ›  Alex B

C++中的C99严格混叠规则

  •  18
  • Alex B  · 技术社区  · 16 年前

    据我所知,GCC支持C++中的所有C99特性。但是C++中如何处理C99严格的混叠呢?

    我知道,在不相关类型之间进行C转换的转换不是严格的别名安全,可能会产生错误代码,但是C++如何?由于严格的混叠不是C++标准的一部分(正确吗?),GCC必须指定语义本身。

    我想 const_cast 和 static_cast 在相关类型之间转换,因此它们是安全的,而 reinterpret_cast 可以打破严格的别名规则。

    这是正确的理解吗?

    3 回复  |  直到 16 年前
        1
  •  33
  •   AnT stands with Russia    12 年前

    不,你可能在混合不同的东西。

    严格的别名规则与C99标准完全无关。严格的混叠规则是从标准化的开始以来,在C和C++中存在的部分标准。C89/90中有一个子句禁止通过另一个类型的左值访问一个类型的对象( 和C++ 98一样( 3.10/15 ). 这就是严格别名的意义所在,不多不少。只是,并不是所有的编译器都希望(或敢于)实施或依赖它。C语言和C++语言有时被用作“高级汇编”语言,严格的混叠规则经常干扰这种用法。正是GCC做出了这一大胆举动,并决定在优化中开始依赖严格的别名规则,这常常会招致那些“程序集”类型的抱怨。

    reinterpret_cast (当然还有C型演员)。然而, static_cast 也可以用于此目的,因为它允许通过使用 void *

    int *pi;
    ...
    double *pd = static_cast<double *>(static_cast<void *>(pi));
    

    const_cast 无法在兼容编译器中中断严格别名。

    restrict 限定符。这与别名直接相关,但它本身并不是所谓的严格别名。

        2
  •  4
  •   Ben Voigt    16 年前

    static_cast 也可以破坏别名规则,因为编译器信任您确保目标类型与对象的实际运行时类型相关。考虑:

    extern void f(double*, int*); // compiler may optimize assuming that arguments don't overlap
    double d;
    void* pv = &d;
    int* pi = static_cast<int*>(pv);
    f(&d, pi); // assumption is violated
    
        3
  •  2
  •   justin    16 年前

    Cpp中的概念是相同的;在这种情况下,您可以使用C样式转换来指导您完成被认为是安全的wrt严格别名。

    简言之:不,使用Cpp铸造的方法(您已经概述)不会安全地涵盖所有情况。打破规则的一种常见方法是使用静态\u cast来转换指针。

    应该