免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 西西弗西
打印 上一主题 下一主题

新鲜出炉的腾讯后台开发三面面试题! [复制链接]

论坛徽章:
0
1 [报告]
发表于 2011-09-29 14:28 |显示全部楼层
本帖最后由 狗蛋 于 2011-09-29 14:38 编辑

以前在cfaq网站看过,0在作为指针用时,可以看做是C的一个关键字,代表“未赋值的指针”或“无效指针”,C标准里也有写;但标准只是规定了0作为指针时,与其它指针比较的行为,没有规定计算偏移的行为。

并且,cfaq还举例说明过,比如0在某些CPU上可能是有效地址,这种平台上的编译器也可以接受指针和0比较或赋值,但会被转换成合适的无效地址。

显然,这样做的话,0可以保证能检测到无效地址;但依赖0指针运算的如offsetof宏就危险了。



我以前也遇到过类似需求。不过当时还不知道有offsetof宏这回事,所以自己搞了个magic num叫OFFSET_BASE,定义成0x1FFFFFF0之类的数值,又搞个注释声明这是个HACK;然后写个宏叫GET_DATA_ITEM_OFFSET,里面强制转换它为待测结构体,用指针减法计算指定成员偏移;当时是测一个有简单构造函数(初始化结构体为0)的结构体,被gcc警告“offsetof宏用于非POD类型,建议使用成员指针”,然后才发现我那个东东居然还有个名堂叫OFFSETOF……于是查gcc的实现,发现它的实现是直接用0,当时也是颇有点不以为然——话说俺定义那个丑陋的OFFSET_BASE本来就是刻意想避开0指针的。

论坛徽章:
0
2 [报告]
发表于 2011-09-29 14:43 |显示全部楼层
本帖最后由 狗蛋 于 2011-09-29 14:44 编辑

回复 151# x5miao


    是的。

在x86平台上,gcc可能定义offsetof为(st*)0的运算,因为这个行为虽然在C里未定义,但在x86上是可以定义的。

同样,如果你用了gcc的offsetof宏,当你的程序被移植到特殊平台时,这个宏的实现可能会被该平台上的gcc重新定义。

所以,用gcc的offsetof宏是安全的;但,窥测gcc的实现、然后仿造gcc的offsetof宏自己搞一个,是不安全的。

因为gcc未必能识别你自己的定义,也不保证能像它自己的实现那样,在其它平台上为你替换一个合法的新实现。

当然,没有跨平台需求的话,这个问题可以忽略。

论坛徽章:
0
3 [报告]
发表于 2011-09-29 15:05 |显示全部楼层
本帖最后由 狗蛋 于 2011-09-29 15:08 编辑
如果是这样,那么offsetof宏的使用就真得有可能造成很严重的后果了。。。
不知道有没有实现的比较笨拙的编 ...
asuka2001 发表于 2011-09-29 14:55



    如果没记错的话,offsetof 应该属于“编译器实现”的东西。

也就是说,某种编译器在某个平台的具体实现换到其它平台就是未定义的,所以不要写自己的offsetof宏,哪怕写的和编译器一模一样也不行。因为这个东西几乎不可能完美的正确实现(当然可以很丑陋的正确实现,比如总是建立一个临时结构体、总是强制转换一个有效指针之类)。

但,使用编译器的offsetof是没问题的。在每个平台如何安全实现offsetof,是编译器作者/移植者的问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP