c++ - C++ 标准在哪里允许指向未定义类型的指针?

标签 c++ forward-declaration language-lawyer

在 C++ 规范中哪里允许这样做?这很酷。我想知道这是如何规范的。我没有意识到规范允许有一个指向未定义类型的指针。

class T;

int main(int argc, char* argv[])
{
   int x;
   T* p = reinterpret_cast<T*>(&x);
   return 0;
}

最佳答案

您所做的可能是合法的,但这取决于 class T 的真实定义,因此我们无法根据您显示的代码确定。

从 C++11 §3.9.2/3 开始:

Pointers to incomplete types are allowed although there are restrictions on what can be done with them.

这些限制在 §3.2/4 中列出:

A class type T must be complete if:

  • an object of type T is defined, or
  • a non-static class data member of type T is declared, or
  • T is used as the object type or array element type in a new-expression, or
  • an lvalue-to-rvalue conversion is applied to a glvalue referring to an object of type T, or
  • an expression is converted (either implicitly or explicitly) to type T, or
  • an expression that is not a null pointer constant, and has type other than void*, is converted to the type pointer to T or reference to T using an implicit conversion, a dynamic_cast or a static_cast, or
  • a class member access operator is applied to an expression of type T, or
  • the typeid operator or the sizeof operator is applied to an operand of type T, or
  • a function with a return type or argument type of type T is defined or called, or
  • a class with a base class of type T is defined, or
  • an lvalue of type T is assigned to, or
  • the type T is the subject of an alignof expression, or
  • an exception-declaration has type T, reference to T, or pointer to T.

第 6 个项目符号出现与此处相关,正如我们在 §5.2.10/7 中看到的那样 reinterpret_cast指针类型之间根据 static_cast 定义:

An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast<cv T2*>(static_cast<cv void*>(v)) if both T1 and T2 are standard-layout types and the alignment requirements of T2 are no stricter than those of T1, or if either type is void. Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified.

但是因为reinterpret_cast static_cast s 至 void*首先,然后到真正的结果指针类型,第 6 个项目符号不适用。

所以,尽管 T,到目前为止你仍然在合法领域内是一个不完整的类型。但是,如果结果是 T不是标准布局类型或对齐要求比 int 更严格,那么 §5.2.10/7 中的最后一句话成立并且您正在调用 UB。

关于c++ - C++ 标准在哪里允许指向未定义类型的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9234217/

相关文章:

c++ - 结构的前向声明不起作用 - 无法弄清楚为什么

c++ - 同样的 clang ,std::initializer_list 程序与 -std=c++14/-std=c++17 的结果不同

c++ - alignof(T*) 对于所有可能的类型都相同吗? sizeof(T*) 呢?

c++ - Sizeof() 的 VBA 等价物?

c++ - GetWindowText 无法处理商标符号

C++ 不命名为类型

c++ - 模板函数中使用的类的前向声明不是由 clang++ 编译的

c++ - 前向声明类型上的 std::vector

c++ - 模板中的字符串文字 - 编译器的不同行为

C++:模板声明中的 "expected ;"