C 可移植性问题
我已经编写了一个程序,可以进行各种处理,并在文件中写入/读取结果 这个“结果”在这样的结构中C 可移植性问题,c,struct,portability,C,Struct,Portability,我已经编写了一个程序,可以进行各种处理,并在文件中写入/读取结果 这个“结果”在这样的结构中 struct res { char id; char* values; int count; long samplenumber; }; 假设我用这样的函数写/读 write( file, &result, sizeof(struct res) ); read(file, &result, filesize(file) ); 我担心的是:如果
struct res
{
char id;
char* values;
int count;
long samplenumber;
};
假设我用这样的函数写/读
write( file, &result, sizeof(struct res) );
read(file, &result, filesize(file) );
我担心的是:如果在32b机器上写入结构,在64机器上读取(或者其他方式),会出现什么问题
我不是在要求对我目前正在做的事情进行任何改进,而是在可移植性方面的问题。根据我的经验,一切都会出问题,因为平台上的类型大小不同 首先,用
stdint.h
#include <stdint.h>
struct res
{
uint8_t id;
char* values;
uint32_t count;
uint32_t samplenumber;
};
或者在单独的写调用中手动写入字符串。这里有4个问题: ~类型的大小可以不同。(使用
stdint.h
中的类型,如uint32\u t
)
~编译器通常会在结构中插入填充,如
struct res
{
char id;
/* unused byte */
/* unused byte */
/* unused byte */
char* values;
int count;
long samplenumber;
};
~整数的Endianness可以不同。例如,3555896322
可以表示为D3 F2 AC 02
或02 AC F2 D3
~
char*
将作为无用指针保存到文件中。您需要自己一个字节一个字节地编写字符串
解决方案:
~使用stdint.h
中的类型
~不要使用结构进行保存。(或者使用所谓的
#pragma pack
,但请记住它不可移植。)
~逐字节写入整数,如
uint32_t var = 3555896322;
putc(var >> 0 & 0xff, file);
putc(var >> 8 & 0xff, file);
putc(var >> 16 & 0xff, file);
putc(var >> 24 & 0xff, file);
~逐字节写入字符串,例如:
const char *ptr = "Hello, young programmer!";
while (*ptr)
putc(*(ptr++), file);
putc('\0', file);
~浮点类型可以直接保存,它们通常在任何地方都具有相同的大小:
float a = 1.23;
fwrite(&a, sizeof (float), 1, file);
哦,对不起,我用C来定义所有的大小:即,<代码>无符号char <代码>,<代码> UTI32 32 t < /代码>(或<代码> iT32×t < /代码>),并考虑更改<代码>长< /C> >,因为这是不同的;您可能希望
uint64\t
这仍然不一定是可移植的,因为成员之间的填充大小可能会改变。有些平台有不同的二进制表示法(大端和小端等)>不使用结构保存。您应该提到的是,有一种叫做“打包”的功能可以避免这种情况<在VC中使用code>#pragma pack或uuuu属性((packed))
可以做到这一点。@user300234他们当然可以,但恐怕这是非常罕见的情况。
float a = 1.23;
fwrite(&a, sizeof (float), 1, file);