我们不要讨论以下代码的坏处,它不是我的,我完全事先同意你,它并不漂亮,而是C-ish和潜在的非常危险:
void * buf = std::malloc(24 + sizeof(int[3]));
char * name = reinterpret_cast<char *>(buf);
std::strcpy(name, "some name");
int * values = reinterpret_cast<int *>(name + 24);
values[0] = 0; values[1] = 13; values[2] = 42;
它的意图非常明确;它是一个"字节块",存储两个不同的数组。类型。要访问不在块前面的元素,它将块解释为 char *
指针并按 sizeof(type[len])
递增指针。
然而,我的问题是,它是否合法C++(11(,如"是否保证将适用于每个符合标准的编译器"?我的直觉说不是,但是 g++ 和 clang 似乎很好有了它。
我希望对此有一个标准的报价;不幸的是,我我自己找不到相关的段落。
完全有效的C++代码(虽然不好,正如你自己指出的那样(。只要字符串不超过 23 个字符,它甚至不会与严格的别名规则冲突,因为您永远不会通过不同类型的指针访问内存中的相同字节。但是,如果字符串超过固定限制,则具有未定义的行为,就像任何其他越界错误一样。
不过,我建议至少使用结构:
typedef struct whatever {
char name[24];
int [3];
} whatever;
whatever* myData = new myData;
std::strcpy(myData->name, "some name");
myData->values[0] = 0; myData->values[1] = 13; myData->values[2] = 42;
这 100% 等效于您给出的代码,除了 new
运算符中的开销更多,而不是直接调用 malloc()
。如果您担心性能,您仍然可以执行whatever* myData = (whatever*)std::malloc(sizeof(*myData));
而不是使用 new。