C++ 中的措辞是什么?标准允许 static_cast(malloc(N));去工作?

发布于 2024-08-28 13:24:58 字数 330 浏览 17 评论 0原文

据我理解 5.2.9 静态转换中的措辞,唯一允许 void* 到对象指针转换的结果是当 void* 首先是逆转换的结果。

在整个标准中,有大量对指针表示形式的引用,并且 void 指针的表示形式与 char 指针的表示形式相同,等等,但它似乎从未明确表示转换任意 void 指针会产生一个指向内存中同一位置的指针,但类型不同,就像类型双关是未定义的,而不双关回到对象的实际类型。

因此,虽然 malloc 明确返回合适内存的地址等,但据我所知,似乎没有任何方法可以实际使用它,可移植。

As far as I understand the wording in 5.2.9 Static cast, the only time the result of a void*-to-object-pointer conversion is allowed is when the void* was a result of the inverse conversion in the first place.

Throughout the standard there is a bunch of references to the representation of a pointer, and the representation of a void pointer being the same as that of a char pointer, and so on, but it never seems to explicitly say that casting an arbitrary void pointer yields a pointer to the same location in memory, with a different type, much like type-punning is undefined where not punning back to an object's actual type.

So while malloc clearly returns the address of suitable memory and so on, there does not seem to be any way to actually make use of it, portably, as far as I have seen.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

撩起发的微风 2024-09-04 13:24:59

C++0x标准草案在5.2.9/13中有:

“指向 cv1 的指针”类型的右值
void”可以转换为右值
输入“指向 cv2 T 的指针”,其中 T 是
对象类型和cv2相同
简历-资格为或更高
cv-资格比,cv1。空值
指针值转换为空
目标类型的指针值。
指向对象的指针类型的值
转换为“指向 cv void 的指针”并且
回来,可能有不同的
简历-资格,应有其
原始值。

但还要注意,强制转换并不一定会产生有效的对象:

 std::string* p = static_cast<std::string*>(malloc(sizeof(*p)));
 //*p not a valid object 

C++0x standard draft has in 5.2.9/13:

An rvalue of type “pointer to cv1
void” can be converted to an rvalue of
type “pointer to cv2 T,” where T is an
object type and cv2 is the same
cv-qualification as, or greater
cv-qualification than, cv1. The null
pointer value is converted to the null
pointer value of the destination type.
A value of type pointer to object
converted to “pointer to cv void” and
back, possibly with different
cv-qualification, shall have its
original value.

But also note that the cast doesn't necessarily result in a valid object:

 std::string* p = static_cast<std::string*>(malloc(sizeof(*p)));
 //*p not a valid object 
一念一轮回 2024-09-04 13:24:59

C++03,§20.4.6p2

内容与标准 C 库头文件相同,但有以下更改:[此处不适用的更改列表]

C99,§7.20.3.3p2-3

(尽管 C++03 是基于 C89,我只有 C99 可以引用,但是我相信这部分在语义上没有变化。)

malloc函数为大小由size和指定的对象分配空间
其值是不确定的。

malloc 函数返回空指针或指向已分配空间的指针。

根据这两个引号,malloc 分配一个未初始化的对象并返回一个指向它的指针,或者返回一个空指针。指向作为 void 指针的对象的指针可以转换为指向该对象的指针(C++03 §5.2.9p13 的第一句,在前面的答案中提到)。


这应该减少你所抱怨的“挥手”,但有人可能会说我正在“解释”C 对 malloc 的定义,如我所愿,例如,注意到 C 说“到分配的空间”而不是“到分配的对象”。对于那些人:首先要意识到“空间”和“对象”在 C 语言中是同义词,其次请向标准委员会提交一份缺陷报告,因为即使是我也不够迂腐,无法继续。 :)

我会给你一个怀疑的好处,并相信你被标准之间的交叉引用、交叉解释和有时令人困惑的集成所绊倒,而不是“空间”与“对象”。

C++03, §20.4.6p2

The contents are the same as the Standard C library header <stdlib.h>, with the following changes: [list of changes that don't apply here]

C99, §7.20.3.3p2-3

(Though C++03 is based on C89, I only have C99 to quote. However, I believe this section is semantically unchanged. §7.20.3p1 may also be useful.)

The malloc function allocates space for an object whose size is specified by size and
whose value is indeterminate.

The malloc function returns either a null pointer or a pointer to the allocated space.

From these two quotes, malloc allocates an uninitialized object and returns a pointer to it, or returns a null pointer. A pointer to an object which you have as a void pointer can be converted to a pointer to that object (first sentence of C++03 §5.2.9p13, mentioned in the previous answer).


This should be less "handwaving", which you complained of, but someone might argue I'm "interpreting" C's definition of malloc as I wish, by, for example, noticing C says "to the allocated space" rather than "to the allocated object". To those people: first realize that "space" and "object" are synonyms in C, and second please file a defect report with the standard committees, because not even I am pedantic enough to continue. :)

I'll give you the benefit of the doubt and believe you got tripped up in the cross-references, cross-interpretation, and sometimes-confused integration between the standards, rather than "space" vs "object".

不回头走下去 2024-09-04 13:24:59

整个标准中有大量对指针表示形式的引用,并且void指针的表示形式与char指针的表示形式相同

是的,确实如此。

因此,虽然 malloc 明确返回合适内存的地址等,但据我所知,似乎没有任何方法可以实际使用它,可移植。

当然有:

void *vp = malloc (1);
char *cp;
memcpy (&cp, &vb, sizeof cp);
*cp = ' ';

有一个小问题:它不适用于任何其他类型。 :(

Throughout the standard there is a bunch of references to the representation of a pointer, and the representation of a void pointer being the same as that of a char pointer,

Yes, indeed.

So while malloc clearly returns the address of suitable memory and so on, there does not seem to be any way to actually make use of it, portably, as far as I have seen.

Of course there is:

void *vp = malloc (1);
char *cp;
memcpy (&cp, &vb, sizeof cp);
*cp = ' ';

There is one tiny problem : it does not work for any other type. :(

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文