使用链接函数作为未初始化内存的输出?

问题描述 投票:0回答:1

假设我有两个输入数组。

std::vector<double> const Matrix = {...};  // 9 elements
std::vector<double> const Vector = {...};  // 3 elements

并且一个输出数组由于某种原因(例如性能)未初始化。

double* Result = std::allocator<double>{}.allocate(3);

我应用了链接的 C 函数,例如 GEMV(BLAS 的矩阵向量乘法)

dgemv(3, 3, (void const*)Matrix.data(), (void const*)Vector.data(), (void*)result)

我知道

result
会有GEMV结果,但是C++也有吗?从法律上来说?

我是否必须祝福内存才能告诉 C++

result
数组已初始化元素?

如果我使用

std::complex<double>
呢? (顺便说一句,它没有一个简单的构造函数)

zgemv(3, 3, (void const*)Matrix.data(), (void const*)Vector.data(), (void*)result)

我是否必须以某种方式(之前或之后)告诉

gemv
,C++ 应该将此内存视为已初始化,即使不是 C++ 初始化它?

我知道在实践中它可能会起作用,但我问是否需要做一些事情才能使其符合标准,即使额外的步骤是无操作的。

c++ initialization language-lawyer
1个回答
0
投票

C++ 标准通常不指定用 C 编写的函数的行为,也不指定 C++ 对象模型如何准确地映射到 C 对象模型,除了一些兼容性建议。

因此从这个角度来看,这个问题超出了标准的范围。

如果我们假设

dgemv
是作为 C++ 函数编写的,并且该函数只是写入某些
Result[i]
,那么从技术上讲,程序将具有未定义的行为。

指定

std::allocator<double>::allocate
来启动返回指针所指向的数组对象的生命周期,但未指定它来启动数组元素的生命周期。也没有指定隐式创建任何其他对象。

因此,当函数尝试写入时,

double
处的
Result[i]
对象不处于活动状态,并且在对象的生命周期之外,它不保存值。

为了创建

double
对象,您需要使用放置新、
std::construct_at
std::allocator<double>::construct
来创建每个对象。

如果是placement-new,您可以在不使用初始化器的情况下编写它,这样它实际上不会写入

double
。其他两个变体将始终使用一个值进行初始化,特别是如果没有给出参数,它们将值初始化为零。

© www.soinside.com 2019 - 2024. All rights reserved.