VC编译奇怪问题,请高手解释一下,疑是VC的bug

zgy166 2004-11-24 09:37:12
代码如下:

#include <stdio.h>

#pragma pack(4)

typedef struct
{
char a[10];
int b;
char c;
}DevFont_Infor;

main()
{
DevFont_Infor font;
int add1 = &(font.b);
int add2 = &font;
printf("add1-add2=%d\n", add1-add2);
printf("&(font.b)-&font=%d\n", &(font.b)-&font);
}

打印出来的结果是:

1. 当定义 #pragma pack(4)时:
add1-add2=12
&(font.b)-&font=3

1. 当定义 #pragma pack(1)时:
add1-add2=12
&(font.b)-&font=2

对结果我觉得很奇怪,哪位有研究过这个问题,讲讲其中的奥妙;
有其他编译器的同仁帮忙试试看在其他编译器上的结果如何。
...全文
261 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
imRainman 2004-11-25
  • 打赏
  • 举报
回复
怀疑楼主是笔误...

#pragma pack(1)是输出:

add1-add2=10
&(font.b)-&font=2

就对了。

下面摘自msdn vc++ reference,稍有改动。

pack(n):
n Specifies the value, in bytes, to be used for packing. The default value for n is 8. Valid values are 1, 2, 4, 8, and 16. The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller.

按照上面所说的,

#pragma pack(4)时:

如果a[0]的位置是0,那么b的位置就是12,

add1 - add2 = 12 ;

&(font.b)-&font= 12/4 = 3 ;

#pragma pack(1)时:

如果a[0]的位置是0,那么b的位置就是10,

add1 - add2 = 10 ;

&(font.b)-&font= 10/4 = 2(取整了) ;
imRainman 2004-11-25
  • 打赏
  • 举报
回复
楼主用的是那个版本的编译器?

按理说当定义#pragma pack(1)时,add1-add2=10才对(VC上是这样的)

难道楼主的编译器不支持pack到1,转而采用了pack(2)?(0.00001%的可能性)
zgy166 2004-11-25
  • 打赏
  • 举报
回复
非常谢谢 imRainman(雨人)
也感谢pacman2000(pacman)(影子传说) and
大家
pacman2000 2004-11-25
  • 打赏
  • 举报
回复
应该是没有规定不同类型指针相减的结果的,但是这里VC大概是以第一个操作数为准做了除以sizeof()大小的操作。sizeof(int)=sizeof(font.b)=4
imRainman 2004-11-25
  • 打赏
  • 举报
回复
To:zgy166(昆深)

两个指针相减,结果是他们的“相对”距离,而不是“绝对”的距离。

比如a和b,假设a在位置0,b在位置8,那么他们的“绝对距离”就是8-0=8;代表他们之间相差的字节

数。

而“相对距离”就要用8/sizeof(a),代表他们之间相差的对象数。
sandrowjw 2004-11-25
  • 打赏
  • 举报
回复
俄哦,两个不同类型的指针相减向哪个类型cast这个有标准吗?
zgy166 2004-11-25
  • 打赏
  • 举报
回复


to imRainman(雨人) :

------------------------------
按照上面所说的,

#pragma pack(4)时:

如果a[0]的位置是0,那么b的位置就是12,

add1 - add2 = 12 ;

&(font.b)-&font= 12/4 = 3 ;

#pragma pack(1)时:

如果a[0]的位置是0,那么b的位置就是10,

add1 - add2 = 10 ;

&(font.b)-&font= 10/4 = 2(取整了) ;

------------------------------

你的
&(font.b)-&font= 12/4 = 3 ;和
&(font.b)-&font= 10/4 = 2(取整了) ;
是怎么算出来的?详细解释一下

zgy166 2004-11-25
  • 打赏
  • 举报
回复
不好意思,有笔误,我用的编译器是VC6.0

1. 当取消定义定义 #pragma pack(n)时:
add1-add2=12
&(font.b)-&font=3

2. 当定义 #pragma pack(4)时:
add1-add2=12
&(font.b)-&font=3

3. 当定义 #pragma pack(1)时:
add1-add2=10
&(font.b)-&font=2
zgy166 2004-11-25
  • 打赏
  • 举报
回复
谢谢大家

我贴的程序我确认没有笔误,我用的编译器是VC6.0

1. 当取消定义定义 #pragma pack(n)时:
add1-add2=12
&(font.b)-&font=3

2. 当定义 #pragma pack(4)时:
add1-add2=12
&(font.b)-&font=3

3. 当定义 #pragma pack(1)时:
add1-add2=12
&(font.b)-&font=2

summerdream228 2004-11-25
  • 打赏
  • 举报
回复
#pragma pack

n (optional)
Specifies the value, in bytes, to be used for packing. The default value for n is 8. Valid values are 1, 2, 4, 8, and 16. The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller.


可是并不是很懂 望指点。。。谢了
nobush 2004-11-24
  • 打赏
  • 举报
回复
楼主的程序是对的,只是:
int add2 = &font; //发生了类型隐式转换

我在Open Watcom下的结果:
32位(即int为4位):与楼主一样
16位:


结果为add1-add2=12
&(font.b)-&font=5
herryhuang 2004-11-24
  • 打赏
  • 举报
回复
字节对齐!!

看一看关于字节对齐的东西就明白啦!

对了,这种用法不是标准,标准对字节对其没有规定,所以在其他编译器下可能不行(我知道BCC不是这样用的)
bigzhu 2004-11-24
  • 打赏
  • 举报
回复
呵呵,已经有人先改了啊!还是把我的贴上来吧
#include <stdio.h>

#pragma pack(1)

typedef struct
{
char a[10];
int b;
char c;
}DevFont_Infor;

void main()
{
DevFont_Infor font;
int add1 =(int) &(font.b);
int add2 =(int) &font;
printf("add1-add2=%d\n", add1-add2);
printf("&(font.b)-&font=%d\n", (int)&(font.b)-(int)&font);
}





#pragma pack(1)的时候:
add1-add2=10
&(font.b)-&font=10



#pragma pack(4)的时候:
add1-add2=12
&(font.b)-&font=12

没有问题啊!


tianhxk 2004-11-24
  • 打赏
  • 举报
回复
依你的程序,在我的VC下编译无法通过
改成如下
#include <stdio.h>
#include<stdlib.h>

//#pragma pack(3)

typedef struct
{
char a[10];
int b;
char c;
}DevFont_Infor;

main()
{
DevFont_Infor font;
int add1 =(int) &(font.b);
int add2 = (int) &font;
printf("add1-add2=%d\n", add1-add2);
printf("&(font.b)-&font=%d\n", (int)&(font.b)-(int)&font);
}
结果为add1-add2=12
&(font.b)-&font=12
version :4.0 1、将生成的代码和事件用两个文件实现。 2、修改了部分Bug; 3、颜色设置做了部分改进; 4、内部集成了VC编译器,和模拟器,生成C文件后可以直接在uCGUIBuilder中编译,运行模拟器了 5、添加代码自动完成功能; 6、添加画线功能。 version : 3.1.0.0 1、修改了选择不同窗体属性窗口不更新的BUG; 2、修改了只能打开一个ucGUIBuilder的功能,现在可以同时启动多个; 3、修复了拖放非ucfrm引起软件错误的Bug; 4、添加了控件ID自动增加功能; 5、添加了控件ID检查功能,控件ID有重复时会有警告; 6、添加了用户自定义字体功能; 7、支持中英文切换(但功能不够完善); 8、支持自动检查更新; 9、修改了不能保存用户自定义ID的BUG; version : 3.0.0.0 重写了部分内核,运行更稳定; 支持窗体设计器的复制、粘贴、剪切、删除、撤销、等基本操作; 支持多控件,对齐、公共属性修改等基本操作; 支持将.ucfrm文件与ucGUIBuilder关联功能; 支持控件自定义ID; 添加了窗体预览功能; 添加了对控件事件的支持; 添加了在线检查更新功能; 等…… version : 2.1.0.5 优化了控件库; 修复了一些Bug; 代码生成窗口中添加了C语言语法高亮显示功能; C文件模板做了部分修改(C文件模板大家可以随意修改为自己喜欢的格式(..\Template\Template.c文件) 但是要保证$$$GUI_WIDGET_CREATE_INFO$$$ $$$Defination$$$ $$$InitDialog$$$ 三个字符串位置不变) 支持设计的窗体保存为文件,并可以打开; 对所有控件属性添加了Description(在属性窗口最下面显示); 窗体布局可以保存,可以自定义为自己喜欢的窗体布局; 修改了部分功能; version : 2.0.0.5 优化了控件库; 修复了一些Bug; 可以生成完整的C文件(包括 资源表,初始化代码等); 修改了部分功能; version : 1.0.0.0 功能很不完善; 还有好多BUG; 目前只能生成资源表; 暂时不能生成其他代码; 大家有什么好的建议可以发送Email 到: ucguibuilder@163.com

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧