在C函数中创建的对象的存在 [英] Existence of objects created in C functions

查看:123
本文介绍了在C函数中创建的对象的存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已建立(参见下文)放置对象的位置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:

  • 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:

[dcl.init]/7 :

默认初始化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:

[basic.life]/1 :

对象或引用的生存期是 对象或参考.据说一个物体是非空的 初始化,如果它是类或聚合类型,并且它是以下之一 它的子对象是由琐碎的构造函数初始化的 默认构造函数.类型为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屋!

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