邪恶的字节块重新解释是否有效C++



我们不要讨论以下代码的坏处,它不是我的,我完全事先同意你,它并不漂亮,而是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。

相关内容

  • 没有找到相关文章

最新更新