一个数据结构定义如下:
typedef struct {
int enabled;
unsigned char type;
int size;
unsigned char name[8]
} MY_STRUCT;
然后定义一函数接口,本意是对MY_STRUCT中的int类型和string进行读取,这里函数接口的作者忽视了unsigned char,视为int类型
_get_my_struct_data(
MY_STRUCT *pD
ata, char *pName, int *
cfgEntry
)
{
...
*
cfgEntry
=
pD
ata->type;
...
}
然后调用:
MY_STRUCT cfg;
_get_my_struct_data(&initCfg
, "type", &
cfg.
type
); /*initCfg是一个全局的变量,initCfg.type = 1,这个并不是关键,关键是第三个参数
&
cfg.
type
*/
printf("
cfg.
type = %d\r\n
",
cfg.
type
); 发现值为0,而不是1;
为什么?
首先说明的 是这代码在大端字节顺序的cpu上运行,第三个参数
&
cfg.
type的地址原来是一个unsigned char类型,而到了函数内部变成了int类型,假设这个地址是a,那么在函数内部,由于大端字节顺序,数据高位置,放在内存低处,
所以内存分布如下:
+++++++++++++++++++
| a | a+1 |a+2| a+3 |
+++++++++++++++++++
赋值
*
cfgEntry
=
pD
ata->type;只对a+3 写入数值1,其他的还是0;而函数返回后打印是unsigned char类型,只是地址a的值,该数值是0;
如何避免这种不细心的函数参数类型强制变化导致的错误,第一,在函数接口定义和使用的时候要严格按照类型进行,第二,不要忽视编译过程的警告
warning: passing argument 3 of '
_get_my_struct_data
' from incompatible pointer type
或者在编译中使用
Werror参数将编译警告视作错误