English 中文(简体)
Does moving values of one type with another type violate strict aliasing?
原标题:

Does it violate strict aliasing rules to move items of any type around using uint32_t, then read them back? If so, does it also violate strict aliasing rules to memcpy from an array of uint32_ts to an array of any type, then read the elements back?

The following code sample demonstrates both cases:

#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:
");
    for (i=0; i<5; i++)
        printf("	%s ", buffer_cc[i]);
    printf("
");

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

    return 0;
}

Please disregard my assumption of a 32-bit platform. Also, if the elements aren t the same size as uint32_t, I know to pad them and copy the correct number of uint32_t s. My question focuses on whether or not doing so violates strict aliasing.

最佳回答

The first loop does technically violate strict aliasing - it accesses uint32_t objects through an lvalue of type char *. It s hard to see how any optimiser would cause you a problem in this specific case, though. If you altered it a little so you were doing something like:

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

You might see the same string printed twice - since the optimiser would be within its rights to only load buffer_cc[0] into a register once, because the second line is only modifying an object of type uint32_t.

The second loop, that memcpys them back, is fine.

问题回答

buffer_cc[0] and strings[3] (for example) are pointers that reference the same memory location but are of the same type, thus don t violate strict aliasing. buffer[0] is not a pointer, thus doesn t violate strict aliasing. Aliasing optimizations arise when dereferencing pointers, so I wouldn t expect this to cause problems.

As you allude to in the code and the last paragraph in your question, the real problem in the sample code arises when pointers and uint32_t are of different sizes.

Also, you can always alias a char* to point to another type without violating strict aliasing, though not vice-versa.





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签