这是否违反严格别名规则移动任何类型的项目周围使用uint32_t的,然后看他们回来呢?如果是这样,它也严格违反重叠规则从uint32_ts的阵列的任何类型的阵列,以memcpy的,然后读取元件背面?

在以下代码示例说明这两种情况下:

#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>

int main(void) {
    const char *strings[5] = {
        "zero", "one", "two", "three", "four"
    };
    uint32_t buffer[5];
    int i;

    assert(sizeof(const char*) == sizeof(uint32_t));

    memcpy(buffer, strings, sizeof(buffer));

    //twiddle with the buffer a bit
    buffer[0] = buffer[3];
    buffer[2] = buffer[4];
    buffer[3] = buffer[1];

    //Does this violate strict aliasing?
    const char **buffer_cc = (const char**)buffer;
    printf("Test 1:\n");
    for (i=0; i<5; i++)
        printf("\t%s ", buffer_cc[i]);
    printf("\n");

    //How about this?
    memcpy(strings, buffer, sizeof(strings));
    printf("Test 2:\n");
    for (i=0; i<5; i++)
        printf("\t%s ", strings[i]);
    printf("\n");

    return 0;
}

请忽略我的32位平台的设想。此外,如果元素不是大小uint32_t的一样,我知道他们垫和复制uint32_t的的正确数量。我的问题集中在是否不这样做违反了严格别名。

有帮助吗?

解决方案

在第一环路确实技术上违反严格别名 - 它通过类型uint32_t的左值访问char *对象。很难看到任何优化器将如何使你的问题在这种特殊情况下,虽然。如果你改变了一点,所以你在做一样的东西:

printf("\t%s ", buffer_cc[0]);
buffer[0] = buffer[3];
printf("\t%s ", buffer_cc[0]);

可能看到相同的字符串印刷两次。 - 由于优化器将其权限只负载buffer_cc[0]内一次到寄存器中,因为第二线仅修改类型uint32_t的目的

第二环路,即memcpys他们回来,是细

其他提示

buffer_cc[0] strings[3](例如)是引用相同的存储器位置,但是相同类型的,从而不违反严格别名指针。 buffer[0]不是指针,从而不违反严格混叠。解引用指针时的混叠出现的优化,因此我不希望这会导致问题。

当你暗示了在代码和你的问题的最后一段,在示例代码中的实际问题时,指针和uint32_t的大小不同就产生了。

此外,可以随时别名char*以指向另一种类型的不违反严格别名,虽然不是反之亦然。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top