5

让我们不要讨论以下代码的坏处,它不是我的,我提前完全同意你的看法,它并不漂亮,而是 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 似乎很好。

我将不胜感激对此的标准报价;不幸的是,我自己找不到相关的段落。

4

1 回答 1

3

这是完全有效的 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 来代替。

于 2013-10-10T14:17:00.267 回答