c++ - 指向限定和非限定类型表示的指针

标签 c++ c constants language-lawyer

将指向非限定类型的指针重新解释为指向限定类型​​的指针是否安全?考虑一个包含指针成员“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/

相关文章:

c++ - 线程接收空字符串

c++ - 如何在 Qt Creator 中使用调试器

不能为 cgminer 自动配置(缺少 AC_CHECK_FUNCS)

c++ - C++ 中的普通常量变量

c++ - Qt with opencv异常处理报错

c++ - Eigen 和 glm 产品产生不同的结果

c - C 程序错误 - 解释

c - 我怎样才能只计算列表中的某些项目?

algorithm - 一种线性时间、恒定空间算法,用于查找列表中出现 1 次的元素

perl - 如何在 Catalyst 应用程序的 Template Tookit 模板中定义常量?