未初始化内存调用外部链接函数的C++标准合规性疑问
关于C++中外部C函数初始化未分配内存的标准合规性问题
假设有两个输入数组:
std::vector<double> const Matrix = {...}; // 9个元素 std::vector<double> const Vector = {...}; // 3个元素
出于性能等原因,使用一块未初始化的输出内存:
double* Result = std::allocator<double>{}.allocate(3);
随后调用外部链接的C函数(例如BLAS库中的矩阵向量乘法函数GEMV):
dgemv(3, 3, (void const*)Matrix.data(), (void const*)Vector.data(), (void*)Result)
我知道Result会存储GEMV的计算结果,但从C标准的角度来说这段代码是否合法?**我是否需要“标记”该内存,告知CResult数组的元素已完成初始化?**
如果使用std::complex<double>(它不具备平凡构造函数)的情况:
zgemv(3, 3, (void const*)Matrix.data(), (void const*)Vector.data(), (void*)Result)
即使不是C完成的初始化,我是否需要通过某种方式(调用前后)告知C该内存已被初始化?
我清楚实际运行中代码可能正常工作,但想了解是否需要执行额外步骤以符合C++标准,即便该步骤是空操作。
补充实现示例
由于当前GCC或Clang尚未支持C23的部分特性,以下是基于C20的等效实现代码:
#include<memory> #include<vector> #include<cstring> void dgemv(int n, int, double const*, double const*, double* result); // 可能的实现(实际为外部链接函数,可能由Fortran编写,确定不会调用placement new) // { // for(int i = 0; i != n; ++i) { // result[i] = 1.2; // } // } // GCC 13.2的C++23尚未实现start_lifetime_as,因此使用C++20的等效实现 template<class T> requires (std::is_trivially_copyable_v<T>) // && std::is_implicit_lifetime_v<T>) // GCC 13.2的C++23尚未实现 T* x_start_lifetime_as(void* p) noexcept { return std::launder(static_cast<T*>(std::memmove(p, p, sizeof(T)))); } int main() { std::vector<double> const Matrix = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0}; std::vector<double> const Vector = {1.0, 2.0, 3.0}; double* Result = std::allocator<double>{}.allocate(3); // 针对数组每个元素调用等效的start_lifetime_as for(int i = 0; i != 3; ++i) { x_start_lifetime_as<double>(std::addressof(Result[i])); } dgemv(3, 3, Matrix.data(), Vector.data(), Result); }
内容的提问来源于Stack Exchange,提问作者alfC
相关产品推荐
相关产品推荐

