在C函数中创建的对象的存在 [英] Existence of objects created in C functions
问题描述
已建立(参见下文)放置对象的位置new
It has been established (see below) placement new
is required to create objects
int* p = (int*)malloc(sizeof(int));
*p = 42; // illegal, there isn't an int
但这是在C中创建对象的一种非常标准的方法.
Yet that is a pretty standard way of creating objects in C.
问题是,如果int
是用C创建并返回到C ++的,是否存在?
The question is, does the int
exist if it is created in C, and returned to C++?
换句话说,以下内容保证合法吗?假设int
对于C和C ++是相同的.
In other words, is the following guaranteed to be legal? Assume int
is the same for C and C++.
foo.h
#ifdef __cplusplus
extern "C" {
#endif
int* foo(void);
#ifdef __cplusplus
}
#endif
foo.c
#include "foo.h"
#include <stdlib.h>
int* foo(void) {
return malloc(sizeof(int));
}
main.cpp
#include "foo.h"
#include<cstdlib>
int main() {
int* p = foo();
*p = 42;
std::free(p);
}
链接到关于放置new
的强制性质的讨论:
Links to discussions on mandatory nature of placement new
:
- 是新放置的将int放入char数组的法律要求?
- https://stackoverflow.com/a/46841038/4832499
- https://groups. google.com/a/isocpp.org/forum/#!msg/std-discussion/rt2ivJnc4hg/Lr541AYgCQAJ
- https://www.reddit.com/r/cpp /comments/5fk3wn/undefined_behavior_with_reinterpret_cast/dal28n0/
- reinterpret_cast创建一个琐碎的默认可构造对象
- Is placement new legally required for putting an int into a char array?
- https://stackoverflow.com/a/46841038/4832499
- https://groups.google.com/a/isocpp.org/forum/#!msg/std-discussion/rt2ivJnc4hg/Lr541AYgCQAJ
- https://www.reddit.com/r/cpp/comments/5fk3wn/undefined_behavior_with_reinterpret_cast/dal28n0/
- reinterpret_cast creating a trivially default-constructible object
推荐答案
是的!但这仅是因为int
是基本类型.它的初始化是空虚操作:
Yes! But only because int
is a fundamental type. Its initialization is vacuous operation:
默认初始化T类型的对象的意思是:
To default-initialize an object of type T means:
-
如果T是(可能是cv限定的)类类型,则考虑构造函数.列举适用的构造函数 ([over.match.ctor]),并选择最佳的初始化方法() 通过重载解决方案.这样选择的构造函数称为 带有一个空的参数列表,以初始化对象.
If T is a (possibly cv-qualified) class type, constructors are considered. The applicable constructors are enumerated ([over.match.ctor]), and the best one for the initializer () is chosen through overload resolution. The constructor thus selected is called, with an empty argument list, to initialize the object.
如果T是数组类型,则每个元素都将默认初始化.
If T is an array type, each element is default-initialized.
否则,不执行初始化.
强调我的.由于int
的未初始化"类似于默认初始化,因此一旦分配存储,它的生命周期就开始了:
Emphasis mine. Since "not initializing" an int
is akin to default initialing it, it's lifetime begins once storage is allocated:
对象或引用的生存期是 对象或参考.据说一个物体是非空的 初始化,如果它是类或聚合类型,并且它是以下之一 它的子对象是由琐碎的构造函数初始化的 默认构造函数.类型为T的对象的生存期始于以下时间:
The lifetime of an object or reference is a runtime property of the object or reference. An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a constructor other than a trivial default constructor. The lifetime of an object of type T begins when:
- 获得具有正确对齐方式和大小的T型存储,并且
- 如果对象具有非空初始化,则其初始化完成,
可以用C ++标准可接受的任何方式来完成存储的分配.是的,即使只是调用malloc
.否则,使用C ++编译器编译C代码将是一个非常糟糕的主意.然而, C ++常见问题解答已建议了多年.
Allocation of storage can be done in any way acceptable by the C++ standard. Yes, even just calling malloc
. Compiling C code with a C++ compiler would be a very bad idea otherwise. And yet, the C++ FAQ has been suggesting it for years.
此外,由于 C ++标准遵循 C标准,其中malloc
是担心的.我认为也应提出措辞.这里是:
In addition, since the C++ standard defers to the C standard where malloc
is concerned. I think that wording should be brought forth as well. And here it is:
7.22.3.4 malloc函数-第2段:
malloc函数为大小为的对象分配空间 由大小指定并且其值不确定.
The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.
值不确定"部分表示存在一个对象.否则,它有什么价值,更不用说不确定的价值了?
The "value is indeterminate" part kinda indicates there's an object there. Otherwise, how could it have any value, let alone an indeterminate one?
这篇关于在C函数中创建的对象的存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!