Reputation: 1330
I have written a program that does all sorts of processing and write/reads the results in a file.
This "result" is in a struct like this
struct res
{
char id;
char* values;
int count;
long samplenumber;
};
and let's say I write/ read with functions like these
write( file, &result, sizeof(struct res) );
read(file, &result, filesize(file) );
My concern is : What could go wrong if the struct is written on a 32b machine and read on a 64 (and other way around) ?
I'm not asking for any improvements of what I'm currently doing, but just about the issues with the way things work in terms of portability.
Upvotes: 2
Views: 88
Reputation: 96579
There are 4 problems here:
~ Sizes of types can be different. (Use types from stdint.h
like uint32_t
.)
~ Compiler usually will insert padding into your struct, like
struct res
{
char id;
/* unused byte */
/* unused byte */
/* unused byte */
char* values;
int count;
long samplenumber;
};
~ Endianness of integers can be different. For example, 3555896322
can be represented asD3 F2 AC 02
or 02 AC F2 D3
.
~ char*
will be saved to file as useless pointer. You need to write string yourself, byte by byte.
Solution:
~ Use types from stdint.h
.
~ Don't use structs for saving. (Or use so called #pragma pack
, but keep in mind that it's not portable.)
~ Write integers byte by byte, like
uint32_t var = 3555896322;
putc(var >> 0 & 0xff, file);
putc(var >> 8 & 0xff, file);
putc(var >> 16 & 0xff, file);
putc(var >> 24 & 0xff, file);
~ Write strings byte by byte, for example:
const char *ptr = "Hello, young programmer!";
while (*ptr)
putc(*(ptr++), file);
putc('\0', file);
~ Floating-point types can be saved directly, they usually have same size everywhere:
float a = 1.23;
fwrite(&a, sizeof (float), 1, file);
Upvotes: 4
Reputation: 11504
From my experience, everything will go wrong because sizes of types are different on platforms.
First of all replace types with ones from stdint.h
#include <stdint.h>
struct res
{
uint8_t id;
char* values;
uint32_t count;
uint32_t samplenumber;
};
Your also shouldn't write string as char*
. When you read it again you just get stale pointer. Use string of predefined size:
char values[256];
Or write string manually in a separate write call.
Upvotes: 3