Dereferencing type-punned pointer will break strict-aliasing rules

后端 未结 7 1476
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-01 01:05

I used the following piece of code to read data from files as part of a larger program.

double data_read(FILE *stream,int code) {
        char data[8];
              


        
7条回答
  •  盖世英雄少女心
    2020-12-01 01:25

    It looks a lot as if you really want to use fread:

    int data;
    fread(&data, sizeof(data), 1, stream);
    

    That said, if you do want to go the route of reading chars, then reinterpreting them as an int, the safe way to do it in C (but not in C++) is to use a union:

    union
    {
        char theChars[4];
        int theInt;
    } myunion;
    
    for(int i=0; i<4; i++)
        myunion.theChars[i] = fgetc(stream);
    return myunion.theInt;
    

    I'm not sure why the length of data in your original code is 3. I assume you wanted 4 bytes; at least I don't know of any systems where an int is 3 bytes.

    Note that both your code and mine are highly non-portable.

    Edit: If you want to read ints of various lengths from a file, portably, try something like this:

    unsigned result=0;
    for(int i=0; i<4; i++)
        result = (result << 8) | fgetc(stream);
    

    (Note: In a real program, you would additionally want to test the return value of fgetc() against EOF.)

    This reads a 4-byte unsigned from the file in little-endian format, regardless of what the endianness of the system is. It should work on just about any system where an unsigned is at least 4 bytes.

    If you want to be endian-neutral, don't use pointers or unions; use bit-shifts instead.

提交回复
热议问题