c++ - 将 T 数组别名为 std::complex<T> 数组合法吗?

标签 c++ language-lawyer strict-aliasing

我知道强类型别名规则。然而,cppreference注意到

An implementation cannot declare additional non-static data members that would occupy storage disjoint from the real and imaginary components and must ensure that the class template specialization does not contain any padding. The implementation must also ensure that optimizations to array access account for the possibility that a pointer to value_type may be aliasing a std::complex specialization or array thereof.

此要求是否允许如下代码合法,即使它不一定是道德的?

std::size_t numDoubles = 100;
double* a = (double*) std::malloc(numDoubles * sizeof(double));
std::complex<double>* b = reinterpret_cast<std::complex<double>*>(a);
DoSomethingWith(b[1]);

如果使用 new[] 生成 double 组,答案会改变吗?

XY 问题说明:我正在尝试对可能不存在的第三方库提供的分配器进行抽象;该分配器返回一个 void*;我试图避免库是否存在的详细信息泄漏到 header 中。所以我有一个如下的结构:

// foo.h
namespace impl {
    void* Allocate(std::size_t numBytes);
}

template<typename T>
T* Allocate(std::size_t num) {
    static_assert(std::is_pod_v<T>);
    return static_cast<T*>(Allocate(num * sizeof(T)));
}


// foo.cpp
#if LIBRARY_PRESENT

void* impl::Allocate(std::size_t numBytes) { return LibraryAllocate(numBytes); }

#else

void* impl::Allocate(std::size_t numBytes) { return std::malloc(numBytes); }

#endif

不幸的是,std::complex 不是 POD,因为它有一个不平凡的默认构造函数。我希望我可以忽略这个问题。

最佳答案

Does this requirement allow code like the following to be legal

即使您使用 a,该代码也不严格合法。直接而不是强制转换为 complex 。 C++ 对象模型不允许您仅仅获取一些内存,将其转换为类型,并假装对象存在于该内存中。无论类型如何(字节类型之外)都是如此。

该代码永远不会创建 double 的数组,因此您无法像 double 数组一样访问内存在那里。您也无法访问 complex<double>就好像它就在那里一样。

Does the answer change if new[] is used to generate the array-of-double?

仅在存在合法数组 double 的意义上。仍然没有complex<double>那里。

规则 std::complex<T>提供的是 you can access its members as though it were an array of two T s 。这并不意味着您可以访问任意两个 T 的数组就好像它是一个 std::complex<T> .

关于c++ - 将 T 数组别名为 std::complex<T> 数组合法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52867194/

相关文章:

c - gcc、严格别名和恐怖故事

c++ - 将整个 ASCII 文件读入 C++ std::string

c++ - unsigned(-0.0) 的行为是否在 C++ 中定义?

C++ strict-aliasing agnostic cast

c++ - c++ 中的复杂 dynamic_cast

c - 将 C 要求应用于未选择的 _Generic 案例

c++ - 将多维数组作为 void * 传递给 extern "C"函数

c++ - GCC 没有链接正确的库

c++ - 带有 cmake 的 CUDA。找不到配置文件

multithreading - Stroustrup指的是std::async的什么限制?