此代码是否违反了严格的别名规则?
我想知道我的代码是否违反了严格的别名规则或其他任何规则。据我所知,我所做的就是在内存中构造一个对象(比如一个 int)。一个 char* 指向内存。然后我让 int* 指向 char* 指向的内存。我在我的代码中所做的事情我认为等同于:
char* memory = (char*)malloc(16);
new (memory) int;
int* intptr = (int*)memory;
*intptr = 7; // I can access this pointer
上面看起来非常好,但这仅仅是因为我在内存缓冲区中构造了一个 int 吗?假设我这样做了:
char* memory = (char*)malloc(16);
// new (memory) int; // Don't create an int here
int* intptr = (int*)memory;
以上似乎仍然有效,因为它与简单的 C 分配没有什么不同:
int* intptr = (int*)malloc(16);
但是,现在这样的事情如何:
int* intptr = (int*)malloc(16);
new (intptr) short;
*intptr = 7; // Is this now illegal?
如果上述内容是非法的,那是否是因为我在该存储中“创建”了一个双精度值?即使 double 只是普通数据并且在某些方面甚至不是“创建”的?我认为这就是非法的原因:
int* intptr = (int*)new short[16];
*intptr = 7;
下面是我的代码,我在内存中的某处构造了一个对象,并将内存转换为指向正确对象的指针(即,在该地址构造的同一对象)。本质上我是从 char* 转换到另一个不相关的对象应该没有关系,对吧?因为在那里构造了正确的对象?
#include <vector>
#include <cassert>
int globalIndexCounter = 0;
template <typename T>
int typeIdx = globalIndexCounter++;
/* Tries to store different types that are indexable, but have to be the same size */
template <int max_size, int element_size>
struct ArrayThatCanStoreDifferentTypes
{
ArrayThatCanStoreDifferentTypes() { memory = (char*)malloc(max_size * element_size); }
template <typename obj_t>
void addObject(const obj_t& obj)
{
int idx = typeIdx<obj_t>;
new (memory + element_size * idx) obj_t(obj);
}
template <typename obj_t>
obj_t& getObject()
{
int idx = typeIdx<obj_t>;
return *(obj_t*)(memory + element_size * idx);
}
char* memory;
};
template <typename T>
struct List
{
std::vector<T> listItems;
};
int main()
{
ArrayThatCanStoreDifferentTypes <16, sizeof(List<int>)> myArray;
myArray.addObject(List<int>{}); // Is constructed at idx 0
myArray.addObject(List<char>{}); // Is constructed at idx 1
myArray.addObject(List<void*>{}); // Is constructed at idx 2
struct mystruct {};
myArray.addObject(List<mystruct>{}); // Is constructed at idx 3
myArray.getObject<List<int>>(); // Get my list of int
myArray.getObject<List<char>>(); // Get my list of char
// These returns of getObject return char*, and I alias it with a pointer to another type, but that's still OK right?
List<int>* ptrAliasingCharPtr = &myArray.getObject<List<int>>();
}
我认为我可以使用指向另一种类型(例如 List*)的指针对 char* 进行别名的原因是该指针指向构造实际 List 的内存/存储。那么在这种情况下它没有违反严格的别名规则吗?