Pointer of union and fwrite operation

Hi,
I have union of pointer.
1
2
3
4
5
6
7
8
union
    {
    short    *two_int;
    int     *four_int;
    double   *eight_real;
    char     *one_ascii;
//    void    *v;
    };

We have write function which write into file.
fwrite (r.one_ascii, 1, i, outstr);

I found one thing,When we write function, we fill only four int in following way.
1
2
r.four_int[0] = x + xoff;
   r.four_int[1] = y + yoff;


So my question,we fill four_int but write one_ascii only.As is it union of pointer. So it does not matter.Please confirm. I am using 64bit machine and do not have any issue in 32 bit machine.

For more information: http://stackoverflow.com/questions/17447838/migration-c-code-32-bit-machine-to-64-bit-machine
As was explained in the stackoverflow thread, reverse is used to deal with endianness issues. i.e. a file written in big-endian order is being read on a little-endian machine or visa versa.

That issue is very different from writing 32 bit integers to a file from a 32 bit application and expecting to read them back correctly in a 64 bit application on the same machine where the endianness is the same. i.e. reverse is not needed unless the file was written in a different endian order.

Bottom line is that you need to know the format of the file so that you know in advance the type of data you're trying to read. From the GdsHeader you have posted, it appears that this type information is encoded in the header.

Assuming that the type indicator correctly tells you that you are trying to read some number of 32 bit integers, then you want to be reading into an explicit 32 bit data type such as int32_t (may or may not be defined as such in your implementation). If you have endianness issues to deal with, then you will want to call reverse on the int32_t data item. You should now have a 32 bit integer in the correct format. Finally, assign that 32 bit integer to a 64 bit integer for your 64 bit application to deal with.
Last edited on
Thanks a lot for your better explanation. I really need this kind of information. Could you please provide input on the union. As in the the code,They allocate memory only for one_ascii and always write one_ascii.
In 32bit the size of pointer is 4 byte and 64bit size of pointer 8 byte. Does it also consideration issue when we deals in 64bit.
The size of the pointer does not matter in this situation. It's not the pointer that is being written to disk, it is what the pointer points to that is being written to disk.

I'm assuming you're trying to maintain the same file format on disk. If you are, then you have an inherrent problem when moving to a 64 bit platform. How are you going to represent a 64 bit int (in memory) in a 32 bit int (on disk) without possibly losing data?

The union is not directly allocating any memory for the data items. It is being used to allow each of the various data types to be addressed through a character pointer (*one_ascii). If you look carefully at the legacy code, you should see that it is writing *one_ascii for some number of bytes depending on the data type of the item (short=2, int=4, etc) that was appropriate on a 32 bit platform.

Writing binary data in character address order is non-portable due to endianness issues.

Last edited on
Again Thanks a lot for your opinion. I have gone through you link and code again. As per my understanding. In Legacy code,They take care of endianness.

As you mentioned, "Writing binary data in character address order is non-portable due to endianness issues.". if I am not wrong,do you mean fwrite is not portable in 64 bit.


I know it is kind very basic question.But if possible could you provide me some input to fix this issue.

Yes,we are writing on the same disk and all machine is upgraded to 64 bit machine.I think,we need not to take care of 32 bit . Please correct me if I did not understand proper way

Apart from this,I have fond one thing.Does int pointer to char pointer typecast may be issue.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

static  void  reverse (int len, char *buf)
{
  TBE;
  char  tmp[24];
  int  i;

  for (i = 0; i < len; i++) tmp[i] = buf[i];
  for (i = 0; i < len; i++) buf[i] = tmp[ (len - 1) - i];
  TBX;
}
inline  void  reverse (int len, unsigned char *s)  { reverse (len, (char *) s); }
inline  void  reverse (int len, short *s)  { reverse (len, (char *) s); }
inline  void  reverse (int len,  int *s)    {

    reverse (len, (char *) s); }
inline  void  reverse (int len, double *s)  { reverse (len, (char *) s); }
Last edited on
do you mean fwrite is not portable in 64 bit

That is not what i said.

fwrite writes whatever you tell it to. It does so in character address order regardless of endianness.

What I said was "Writing binary data in character address order is non-portable" since the order of the bytes is different between a big-endian and a little-endian platform.

Lets take the case of a 16 bit short.
On a big-endian machine, the bytes are
0: MSB 1: LSB
On a little-endian machine, the byte are:
0: LSB 1: MSB

So you need to know the order the bytes were written and and the order that you want the bytes. If not the same, then you need to call reverse.

You also need to make sure you are using compatible data types. As has been pointed out several times, sizeof(int) is different on 32 bit and 64 bit machines.
You can't simply read a 32 bit int (4 bytes) into a 64 bit int (8 bytes) using character I/O without taking special care as to alignment, byte order and padding.

Thanks. for reply. I will take size of int as you have mentioned previous thread. I have small question on the reverse function.
We pass from the code (sizeof(int),value) => reverse(4,1485).

The hexadecimal of this value 5cd and the reverse function return me cd05. it looks me it is converted into Little Indian If I am not wrong.

So I am stuck here,As we are converting Little indian than How Will able to preserve data.

I have also tried to with 8 byte and found that it was truncate by 8.


Why am I concentrating on the reverse function,I feel it is only the place where I need to take care . Please correct me If I am wrong.
Last edited on
thanks to all..... for helpful replies...
Topic archived. No new replies allowed.