C++Builder的BUG???(100分)

  • 主题发起人 主题发起人 滨滨
  • 开始时间 开始时间

滨滨

Unregistered / Unconfirmed
GUEST, unregistred user!
typedef struct {
APW_EV_TYPE type;
union {
HANDLE string_value;
do
uble real_value;
LONG long_value;
LPSTR string_ptr;
} value;
} APWC_EVALPB, FAR *APWC_EVALPB_PTR;
int a,b,c;
APWC_EVALPB eval;
a=sizeof(eval);
b=sizeof(eval.value);
c=sizeof(eval.type);
运行中发现a=16,b=8,c=4,为什么a-b-c=4多出了4个字节?
以上是我在开发一个dll时发现的,数据类型是第三方提供的接口,不能改动,用VC和Delphi都成功了,就是CB不成功,才发现CB的数据多了4个字节,为什么???在union的问题上,CB是不是非标准的?如何用CB实现同样的内存结构?
 
我自己解决了。
在advanced compiler中设置Data alignment为非Quad word即可。不知为什么默认为这个。
 
和缓存有关系。
Pentium III的缓存是256Bit对齐的。
如果一次读取跨越边界,就要分成两次读取。
设置成4个字节也是可以的,只要读取数据不跨越
缓存边界。
但是如果使用int64或者double类型的就有可能跨越边界。
所以设定成8个字节。

这是我一个同学给的解释,如果不明白,我明天如果有时间会详细说明一下
我个人有另外一个解释,虽然和他的不冲突,但他的听起来更可信一些
 
由于 BCB 是用 VCL ---- 实际上就是 Delphi 库,
为保持一致,所以与 Delphi 一致采用 QWORD(4字)对齐。
VC 的默认对齐好象是 BYTE 吧。
 
同意ddev的观点,是数据类型的问题。
另外,在编程时也应该时刻注意数据类型的兼容问题,下面列出Delphi和C++,以及Win32API与C的数据
类型对照表,以后遇到拿不准的地方看一下,有好处的。
『Delphi和C++数据类型对照表』
Delphi 字长/值域 C++
ShortInt 8位有符号整型 signed char
SmallInt 16位有符号整型 short
LongInt 32位有符号整型 int
Byte 8位无符号整型 unsigned char
Word 16位无符号整型 unsigned short
Integer 32位有符号整型 int
Cardinal 32位无符号整型 unsigned int
Boolean 真/假 bool
ByteBool 真/假 或 8位无符号整型 unsigned char
WordBool 真/假 或 16位无符号整型 unsigned short
LongBool 真/假 或 32位无符号整型 BOOL (WinAPI)
AnsiChar 8位无符号字符 char
WideChar 宽字编码字符 wchar_t
Char 8位无符号字符 char
AnsiString Delphi的字符串类 AnsiString 类
String[n] 老式的Delphi字符串, n = 1..255字节 SmallString<n> 模板类
ShortString 老式的Delphi字符串, 255字节 SmallString<255>
String Delphi的AnsiString类 AnsiString
Single 32位浮点数 float
Double 64位浮点数 do
uble
Extended 80位浮点数 longdo
uble
Real 32位浮点数 do
uble
Pointer 32无类型指针 void *
PChar 32位字符型指针 unsigned char *
PAnsiChar 32位ANSI型字符指针 unsigned char *
Comp 64位浮点数 Comp 类
OleVariant OLE可变类型值 OleVariant 类
『Win32API与C语言数据类型对照表』
Win32API C语言
HANDLE void*
BYTE unsigned char
SHORT short
WORD unsigned short
INT int
UINT unsigned int
LONG long
BOOL long
DWORD unsigned long
ULONG unsigned long
CHAR char
LPSTR char*
LPCSTR const char*
LPWSTR wchar_t*
LPCWSTR const wchar_t*
FLOAT float
DOUBLE do
uble
 
hd-copy说的不错.
 
对,可能就是以前学tc时候说的那个强制类型转换的事儿。
我是来混分的。^_^
 
昨天我和我同学详细讨论了一下这个问题,结果如下:
之所以VCL缺省用Quad Word是为了能够避免一个数据被读入时分两次读取
1、P3的缓存以256Bit为一块,如果数据在同一块中,那么这个数据在读入CPU时只需要
一次读取操作;如果数据被分在不同的块,那么读入时就会分两次,然后从两块中分
离出需要的部分再拼合起来,这就延长了处理的时间,也就是降低了程序的执行效率
例如:一个char(a)和连续的四个Int64(b、c、d、e)分布在缓存中,a占据着一个
数据块的开头,如果这时数据对齐选的是Quad Word,那么a、b、c、d会在一个块中,
e在另一个块中,对每一个数据都能一次读取完毕;如果数据对齐选的是Byte,那么a、
b、c、d和e的前七个字节(也就是低位的56位)会在一个数据块中,e的高位8字节在
另一块,这样对a、b、c、d的读取都可以一次完成,而对e就要读两次。

2、现在的CPU对外的数据总线至少是64位的(据说Intel的有128位),为了能提高数据传输
效率,用8字节对齐是最好的
按这样分析,如果数据对齐选的是Byte,只有char、unsigned char不受影响;如果选
的是Word,不受影响的数据类型增加了short、unsigned short;如果选了Double Word,
int、unsigned int、float也不受影响;如果选Quad Word,那么除了longdo
uble外都
不会有影响。
 
可能是我太笨了
在d下怎么彻底实现union?
 
我发现,还是delphi 好用.什么都方便点.不知道各位是否有这样的意见.
 
I know what you mean!!
 
后退
顶部