将指向非限定类型的指针重新解释为指向限定类型的指针是否安全?考虑一个包含指针成员“void *ptr”的标准布局类型和另一个等效定义的标准布局类型,但具有“const void *ptr”。这些类型的布局是否兼容,这个答案是否取决于语言版本或 C 和 C++ 之间的版本?
动机:
有时在与 C 程序交互时,会定义一个结构分组参数到某种类型的缓冲区。对于 const 正确性,输入缓冲区应具有指向底层缓冲区的 const 指针,但输出缓冲区显然必须是可变的。
struct s1 { const void *ptr; }
struct s2 { void *ptr; }
const void *get_in_ptr(void);
void *get_out_ptr(void);
void alg(const s1 *in, const s2 *out);
void f()
{
s1 in_arg = { get_in_ptr() };
s2 out_arg1 = { get_out_ptr() };
s2 out_arg2 = { get_out_ptr() };
/* First algorithm pass. */
alg(&in_arg, &out_arg1);
/* Second algorithm pass. */
alg((const s1 *)&out_arg1, &out_arg2); /* Is this legal? */
}
请在任何答案中引用相关标准出版物。
最佳答案
C11 states :
For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to the q-qualified version of the type; the values stored in the original and converted pointers shall compare equal.
因此,转换为合格版本是安全的,但反之则不然。丢弃 - 特别是 const
或 volatile 可以使用不同的内存访问,例如对于在程序存储器(PIC、AVR)中存储 const
变量的哈佛架构。而且标准很clear关于后果:
If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined. If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined.
简而言之:一般来说,丢弃这些限定符不是安全的。但是,该标准并未提及对 ex-const
对象的读取访问。
有关其他限定符和更多详细信息,请自行阅读。
对于结构布局:C 使用类型/布局的兼容性,而不是 C++。因此,如果两种类型使用相同的布局/标准类型,而不是相同的类型名称,则它们是兼容的。
关于c++ - 指向限定和非限定类型表示的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32106803/