• 主页
  • Windows SDK/API
  • 基础类
  • ActiveX
  • 数据库及相关技术
  • 网络及通讯开发
  • VCL组件使用和开发

★ BCB6的严重BUG! 关于字节对齐问题 ★

jishiping 2002-04-02 07:55:01
在 BCB6 自带的头文件中,所有的字节对齐都不起作用,即
#include <pshpack1.h>
#include <pshpack2.h>
#include <pshpack4.h>
#include <pshpack8.h>
#include <poppack.h>
都没有效果。当然,并不是所有的结构定义都受影响。比如:
typedef struct tagBITMAPFILEHEADER { // bmfh
WORD bfType;
DWORD bfSize; //由于对齐布起作用,在这之前添加两个字节,使bfSize的地址对齐到4的倍数
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
在C++Builder6中大小是16,应该是14。

typedef struct tagBITMAPINFOHEADER{ // bmih
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
由于这个结构不需要对齐指令,所以不受影响。
这意味着凡是你用到受影响的结构,你的程序就会有问题!!!

修改方法,将上面的五个文件(pshpack*.h, poppack.h)开头的
#pragma option push -b -a8 -pc -A- /*P_O_Push*/
和结尾的
#pragma option pop /*P_O_Pop*/
去掉,就可以了。
...全文
455 点赞 收藏 19
写回复
19 条回复
猛禽 2002年12月28日
楼上怎么把这贴给翻出来了。^_^

BCB6的UPD2已经改正这个BUG
回复 点赞
gk0205 2002年12月27日
收藏
回复 点赞
猛禽 2002年04月13日
cker(〖烟波浩淼三千里、人鬼殊途五百年〗) 兄不愧是高人啊,说得这么明白了,大家应该知道了吧,这的确是一个BUG(其实是疏乎)造成的。
回复 点赞
#pragma option push -b -a8 -pc -A- /*P_O_Push*/这一行中
系统默认的对齐选项Quad word (8-byte)对齐 就是 -a8,这一行将系统默认的几个编译选项保护起来了...

然后又唧唧歪歪的设置了n下
...调整对齐方式

最后#pragma option pop /*P_O_Pop*/
居然又把系统默认的编译选项全部恢复了。前面的调节还有屁用。
你说他们是不是很白.....
回复 点赞
LoveTide 2002年04月07日
不是BUG, 是编译选项的问题。。。
VC默认的是8字节对齐,你可以看一下 sizeof(一个结构) 的大小就知道了。

#pragma pack (push,1)
.....
....
#pragma pack (pop)
回复 点赞
猛禽 2002年04月07日
呵,实践是检验真理的唯一标准啊,我也试过了,的确如此,就是这四个头文件的错,不过我担心的是这样改过其它地方会不会有问题。
回复 点赞
781014 2002年04月04日
相信会有补定的。
回复 点赞
jishiping 2002年04月04日
up
回复 点赞
毕加索的画 2002年04月03日
to jishiping (JSP)
你自已不是说了吗
WORD bfType;
DWORD bfSize; //由于对齐布起作用,在这之前添加两个字节,使bfSize的地址对齐到4的倍数

所以bfType占4 byte,那么

bfType 4 byte (加了2 byte用以对齐)
bfSize 4 byte
bfReserved1 2 byte
bfReserved2 2 byte
bfOffBits 4 byte

不就是16 byte吗?
回复 点赞
whitelion 2002年04月03日
cc
回复 点赞
Ykang 2002年04月03日
我比较了BCB50和BCB60的pshpack*.h,poppack.h,发现BCB50相应的头文件里面就没有你提示要删除的那头尾两句,真不知道Borland为什么要加上那两句,是不是写头文件写顺手啦,顺便带上的,呵呵
回复 点赞
Ykang 2002年04月03日
老兄,我在BCB50和BCB60分别测试了你的那段代码,发现在BCB60中我无论如何设置对齐方式,得到的bfh.bfSize都为0,而BCB50是对的,看来确实是一个BUG啊。
不过,这么严重的错误怎么没有测试出来啊!!
回复 点赞
jishiping 2002年04月03日
redpower(常宁):
你究竟懂不懂啊?别的我就不说了,先来看看BITMAPFILEHEADER的定义:
#include <pshpack2.h>
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
#include <poppack.h>

用pshpack2.h的目的就是无论你的程序选用哪种对齐方式,BITMAPFILEHEADER
始终使用 WORD 对齐。可是BCB6的 pshpack2.h 定义有问题,结果BITMAPFILEHEADER
不是以 WORD 对齐,所以会有问题。对齐方式与16位还是32位程序无关。只不过是
不同的开发工具有不同的缺省的对齐方式。但是用 pshpack*.h 后,程序强制
使用你指定的对齐方式。在你的程序中没有指定对齐方式时,程序使用你自己
设定的对齐方式。
回复 点赞
常宁 2002年04月03日
BCB的定义是正确的,如果api中的这个定义如你所说,只能说她是面向16位系统的,因此宏定义不一样。在16位系统,是2字节对齐的。
所以问题不是BCB是否有BUG,而是你的处理是否正确,说穿了,还是你的处理方法不对。
顺便说一句,BCB支持2字节对齐,在project中可以设置,但我劝你最好别这么做。另外我希望别没是老提BUG之类的标题好不好!!!!
回复 点赞
jishiping 2002年04月03日
大家还没有明白我的意思吧。BMP文件的文件头信息是14个字节,用结构
BITMAPFILEHEADER 来表示。bfType 应该是2个字节(内容为BM),后面紧
跟的4个字节是BMP文件的大小。可是在BCB6里,结构 BITMAPFILEHEADER
的大小变成了16,就是说,bfSize你的数据是BMP文件的第4到7个字节的
数据,而不是第2到5个字节的数据,所以结构里面的数据就乱了。比方说:
BITMAPFILEHEADER bfh;
FILE* fp = fopen("c:\\test.bmp");
if (fp != NULL) {
fread(&bfh, 1, sizeof(bfh), fp);
fclose(fp);
}
这样你读出的数据(bfh.bfSize, bfh.bfReserved2, bfh.bfOffBits)全部
是错的。现在明白吗?Windows API里定义的结构太多了,如果你用到受影
响的结构,你的程序就会出错!
回复 点赞
常宁 2002年04月03日
to kingcaiyao(AKing)
to jishiping(JSP)
你们两个的星都比我多,不会看不出来这个问题吧,我觉得办事认真点,别把别人引入歧途
回复 点赞
常宁 2002年04月03日
to jishiping (JSP)
别耸人听闻好不好,我怎么算都是16byte,你是不是看花眼了,或是根本不懂这个?
4+4+2+2+4=16 难道已对这个有异议?
我还是那句话,说开发环境有BUG的人,最好自己反省一下!!!!!!
回复 点赞
kingcaiyao 2002年04月02日
很有见地。
回复 点赞
jishiping 2002年04月02日
为了能让更多的人知道这个BUG,我推一下。请大家多多发言。
回复 点赞
发动态
发帖子
C++ Builder
创建于2007-08-02

2563

社区成员

10.2w+

社区内容

C++ Builder相关内容讨论区
社区公告
暂无公告