我正在尝试统一一个ARM项目(特别是运行Linux 2.6.33.3的i.MX27 CPU,使用GCC 4.3.2编译)的SQLite交互方法。作为其中的一部分,我创建了一个带有union的结构,该结构用于保存值以绑定到预准备语句。
#define SQLITE_DATA_CHARACTER_STRING_MAX 1024
typedef struct
{
int data_type;
union
{
int integer;
double floating_point;
unsigned char character_string[SQLITE_DATA_CHARACTER_STRING_MAX];
};
}sqlite_data;
最初,这是int
,float
,char
。我想使用long long
,double
和char
。但是,这似乎导致了一个问题。如上所述,以下代码生成可预测的输出:
int data_fields = 15;
int data_fields_index = 0;
sqlite_data data[data_fields];
LogMsg(LOG_INFO, "%s: Assigning", __FUNCTION__);
for(data_fields_index = 0; data_fields_index < data_fields; data_fields_index++)
{
data[data_fields_index].data_type = (100 + data_fields_index);
data[data_fields_index].integer = (1000 + data_fields_index);
LogMsg(LOG_INFO, "%s: data[%d] - %d; type - %d", __FUNCTION__, data_fields_index, data[data_fields_index].integer, data[data_fields_index].data_type);
}
其输出是:
Assigning
data[0] - 1000; type - 100
data[1] - 1001; type - 101
data[2] - 1002; type - 102
data[3] - 1003; type - 103
data[4] - 1004; type - 104
data[5] - 1005; type - 105
data[6] - 1006; type - 106
data[7] - 1007; type - 107
data[8] - 1008; type - 108
data[9] - 1009; type - 109
data[10] - 1010; type - 110
data[11] - 1011; type - 111
data[12] - 1012; type - 112
data[13] - 1013; type - 113
data[14] - 1014; type - 114
但是,如果我只进行一次更改(integer
类型为long long
),那么一切都会崩溃。所以,改变如下:
typedef struct
{
int data_type;
union
{
long long integer;
double floating_point;
unsigned char character_string[SQLITE_DATA_CHARACTER_STRING_MAX];
};
}sqlite_data;
生成此输出:
Assigning
data[0] - 1000; type - 0
data[1] - 1001; type - 0
data[2] - 1002; type - 0
data[3] - 1003; type - 0
data[4] - 1004; type - 0
data[5] - 1005; type - 0
data[6] - 1006; type - 0
data[7] - 1007; type - 0
data[8] - 1008; type - 0
data[9] - 1009; type - 0
data[10] - 1010; type - 0
data[11] - 1011; type - 0
data[12] - 1012; type - 0
data[13] - 1013; type - 0
data[14] - 1014; type - 0
我尝试使用#pragma pack(6)
对它们进行去实现,并将该数组放在堆上,所有结果都相同:int
有效,long long
没有。
这里发生了什么?
答案 0 :(得分:6)
您没有告诉printf()
期待long long
。在格式字符串中使用%lld
而不是%d
。
答案 1 :(得分:4)
Sneftel绝对正确。问题是您没有指定导致未定义行为的long long
。为了帮助您将图片可视化如下:
"%s: data[%d] - %d; type - %d"
%s - [✓] __FUNCTION__ is a valid string.
%d - [✓] data_fields_index is an int
%d - [x] data[data_fields_index].integer is a long long, this will only read
the first 4 bytes of an 8 byte integer.
%d - [x] this is likely reading the last 4 bytes of
data[data_fields_index].integer which will be 0 for smaller numbers
on a little endian architecture.
因此,long long 1000将以小端存储在内存中:
[0x00 0x20 0x00 0x00 0x00 0x00 0x00 0x00]
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
first %d second %d
将格式更改为"%s: data[%d] - %lld; type - %d" will fix this.