在C函数中创建的对象的存在

Pas*_* By 18 c c++ object-lifetime language-lawyer

已经建立(见下文)new创建对象需要放置

int* p = (int*)malloc(sizeof(int));
*p = 42;  // illegal, there isn't an int
Run Code Online (Sandbox Code Playgroud)

然而,这是在C中创建对象的一种非常标准的方式.

问题是,int如果是在C中创建并返回到C++ ,是否存在?

换句话说,以下是否保证合法?假设intC和C++是相同的.

foo.h中

#ifdef __cplusplus
extern "C" {
#endif

int* foo(void);

#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)

foo.c的

#include "foo.h"
#include <stdlib.h>

int* foo(void) {
    return malloc(sizeof(int));
}
Run Code Online (Sandbox Code Playgroud)

main.cpp中

#include "foo.h"
#include<cstdlib>

int main() {
    int* p = foo();
    *p = 42;
    std::free(p);
}
Run Code Online (Sandbox Code Playgroud)

有关安置强制性质的讨论的链接new:

Sto*_*ica 5

是! 但这只是因为int是基本类型。它的初始化是空操作:

[dcl.init] / 7

要默认初始化类型T的对象意味着:

  • 如果T是(可能是cv限定的)类类型,则考虑构造函数。枚举适用的构造函数([over.match.ctor]),并通过重载解析选择最适合初始化器()的构造函数。如此选择的构造函数被调用,并带有一个空的参数列表以初始化对象。

  • 如果T是数组类型,则每个元素都将默认初始化。

  • 否则,不执行初始化。

强调我的。由于“不初始化” int类似于默认初始化,因此一旦分配存储,它的生命周期就开始了:

[basic.life] / 1

对象或引用的生存期是对象或引用的运行时属性。如果对象属于类或聚合类型,并且其或其子对象之一由普通的默认构造函数以外的构造函数初始化,则称该对象具有非空初始化。类型为T的对象的生存期始于以下情况:

  • 获得具有适合T型的对齐方式和大小的存储,并且
  • 如果对象具有非空初始化,则其初始化完成,

存储分配可以通过C ++标准可接受的任何方式进行。是的,甚至只是打电话给malloc。否则,使用C ++编译器编译C代码将是一个非常糟糕的主意。但是,C ++常见问题解答已经建议了多年了


另外,由于C ++标准推迟到C标准,其中malloc关注。我认为也应提出措辞。这里是:

7.22.3.4 malloc函数-第2段

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

“值不确定”部分表示存在一个对象。否则,它有什么价值,更不用说不确定的价值了?