我想知道 C11 标准中是否定义了到 const 数据类型指针的隐式转换:
T x;
const T *p = &x;
指向T
类型对象的指针被隐式转换为指向const T
类型对象的指针。 C11 标准中是否定义了这种隐式转换? (我知道允许这样做是有意义的以及它有多么有用。我只是想知道它在标准中的定义位置)
此外,根据 C11 是否禁止从类型 T**
到 const T**
的隐式转换?
T *p;
const T **pp = &p;
这是一个众所周知的有问题的部分,因此 GCC 和 LLVM/clang 发出警告。我仍然想知道根据 C11 标准是否允许这样做。我只在 §6.5.16.1P6 中发现了一条评论,指出这应该是一个约束违规。但是,我不认为应该违反哪个约束。我再次知道这应该被禁止,并且这种隐式转换可能会导致微妙的问题。我只是想知道这是否是根据 C11 定义的(未)行为。
再说一遍,我的两个问题不是关于这是否好(这里已多次回答),而是 C11 标准如何/在哪里定义它。
为了完整起见,这里提供了第二个示例出现问题的原因的链接:http://c-faq.com/ansi/constmismatch.html
最佳答案
A pointer to an object of type T is implicitely converted into a pointer to an object of type const-T. Is this implicit conversion somewhere defined in the C11 standard?
是的。这种隐式转换是标准强制要求的。
Paragraph 3节6.5.4 Cast Operators说的是
Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast.
第 3 点下引用的 6.5.16.1 说:
the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
因此,const T *p = &x;
的隐式转换成立,因为您只是添加限定符,而不是删除它们。
const T **pp = &p;
不属于此范围,因此您需要显式强制转换(C++ 允许 const T*const*pp = &p;
(需要第二个常量)但 C 仍然不需要。)
只要对齐匹配(对于指向不同限定类型的指针,它们就会匹配),就 UB 而言,通过显式强制转换进行的指针转换不是问题,因为 6.3.2.3p7保证:
A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned68) for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.
但您需要注意访问/取消引用,这将受 strict aliasing rule 的控制:
An object shall have its stored value accessed only by an lvalue expression that has one of the following types:88)
a type compatible with the effective type of the object, a qualified version of a type compatible with the effective type of the object, a type that is the signed or unsigned type corresponding to the effective type of the object, a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object, an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or a character type.
关于c - 隐式指针到 Const-T 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49633108/