正在添加到"char *"指针UB,当它实际上没有指向char数组时? [英] Is adding to a "char *" pointer UB, when it doesn't actually point to a char array?

查看:114
本文介绍了正在添加到"char *"指针UB,当它实际上没有指向char数组时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++ 17( expr.add/4 )说:

C++17 (expr.add/4) say:

将具有整数类型的表达式添加或减去时 从指针开始,结果具有指针操作数的类型.如果 表达式P指向具有n的数组对象x的元素x [i] 元素,表达式P + J和J + P(其中J的值为j) 如果0≤i+j≤n,则指向(可能是假设的)元素x [i + j]; 否则,行为是不确定的.同样,表达式P-J 如果0≤ij≤n,则指向(可能是假设的)元素x [ij]; 否则,行为是不确定的.

When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n; otherwise, the behavior is undefined. Likewise, the expression P - J points to the (possibly-hypothetical) element x[i−j] if 0≤i−j≤n; otherwise, the behavior is undefined.

struct Foo {
    float x, y, z;
};

Foo f;
char *p = reinterpret_cast<char*>(&f) + offsetof(Foo, z); // (*)
*reinterpret_cast<float*>(p) = 42.0f;

该行是否标记有(*)UB? reinterpret_cast<char*>(&f)不是指向char数组,而是指向浮点数,因此根据引用的段落,它应为UB.但是,如果它是UB,则offsetof的用途将受到限制.

Has the line marked with (*) UB? reinterpret_cast<char*>(&f) doesn't point to a char array, but to a float, so it should UB according to the cited paragraph. But, if it is UB, then offsetof's usefulness would be limited.

是UB吗?如果没有,为什么不呢?

Is it UB? If not, why not?

推荐答案

请参见 CWG 1314

根据6.9 [basic.types]第4段,

According to 6.9 [basic.types] paragraph 4,

类型T的对象的对象表示形式是由类型T的对象占用的N个无符号字符对象的序列,其中N等于sizeof(T).

The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof(T).

和4.5 [介绍对象]第5段,

and 4.5 [intro.object] paragraph 5,

普通可复制或标准布局类型(6.9 [basic.types])的对象应占据连续的存储字节.

An object of trivially copyable or standard-layout type (6.9 [basic.types]) shall occupy contiguous bytes of storage.

这些段落是否使标准布局对象中的指针算术运算(第8.7节[expr.add]段5)得到了明确定义(例如,用于编写自己的memcpy版本)?

Do these passages make pointer arithmetic (8.7 [expr.add] paragraph 5) within a standard-layout object well-defined (e.g., for writing one's own version of memcpy?

理论值(2011年8月):

当前的措词足够清楚,表明可以使用这种用法.

The current wording is sufficiently clear that this usage is permitted.

我强烈不同意CWG的说法,即当前措词已经足够清楚",但这是我们的裁定.

I strongly disagree with CWG's statement that "the current wording is sufficiently clear", but nevertheless, that's the ruling we have.

我将CWG的响应解释为,建议将指向unsigned char的指针转换为普通可复制或标准布局类型的对象(出于指针算术的目的),应将其解释为指向unsigned char数组的指针大小等于所讨论对象的大小.我不知道他们是否打算使用char指针或(从C ++ 17开始)使用std::byte指针. (也许如果他们决定进行实际澄清,而不是声称现有措词足够清楚,那么我会知道答案的.)

I interpret CWG's response as suggesting that a pointer to unsigned char into an object of trivially copyable or standard-layout type, for the purposes of pointer arithmetic, ought to be interpreted as a pointer to an array of unsigned char whose size equals the size of the object in question. I don't know whether they intended that it would also work using a char pointer or (as of C++17) a std::byte pointer. (Maybe if they had decided to actually clarify it instead of claiming the existing wording was clear enough, then I would know the answer.)

(另一个问题是,是否需要std::launder才能使OP的代码定义清楚.我在这里不做介绍;我认为这值得一个单独的问题.)

(A separate issue is whether std::launder is required to make the OP's code well-defined. I won't go into this here; I think it deserves a separate question.)

这篇关于正在添加到"char *"指针UB,当它实际上没有指向char数组时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆