免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
151 [报告]
发表于 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未必能识别你自己的定义,也不保证能像它自己的实现那样,在其它平台上为你替换一个合法的新实现。

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

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
152 [报告]
发表于 2011-09-29 14:50 |只看该作者
本帖最后由 asuka2001 于 2011-09-29 14:54 编辑

稍微有些好奇gcc的实际行为,以前只是认为直接offsetof就是把offset的编译常量返回了,所以反编译了程序看看
08048494 <main>:
8048494:       55                      push   %ebp
8048495:       89 e5                   mov    %esp,%ebp
8048497:       83 e4 f0                and    $0xfffffff0,%esp
804849a:       83 ec 10                sub    $0x10,%esp
804849d:       b8 00 00 00 00          mov    $0x0,%eax
80484a2:       83 c0 06                add    $0x6,%eax

80484a5:       89 44 24 04             mov    %eax,0x4(%esp)
80484a9:       c7 04 24 80 85 04 08    movl   $0x8048580,(%esp)
80484b0:       e8 0b ff ff ff          call   80483c0 <printf@plt>
80484b5:       b8 00 00 00 00          mov    $0x0,%eax
80484ba:       c9                      leave
80484bb:       c3                      ret   

从汇编上看,offset gcc是直接获得的6,然后把它和基址0相加。由于不需要解引用指针,所以没有引起段错误。。。
就这点上看,还真可以说offset虽然是编译常量,但是offsetof宏其实还是在运行期返回的值,所以我刚才的说法是错误的!
之所以没有出现段错误,仅仅是因为并不需要解引用null指针!

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
153 [报告]
发表于 2011-09-29 14:55 |只看该作者
如果是这样,那么offsetof宏的使用就真得有可能造成很严重的后果了。。。
不知道有没有实现的比较笨拙的编译器,会让offsetof宏来个段错误:)这个很好奇嘿嘿

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



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

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

但,使用编译器的offsetof是没问题的。在每个平台如何安全实现offsetof,是编译器作者/移植者的问题。

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
155 [报告]
发表于 2011-09-29 15:06 |只看该作者
回复 155# 狗蛋

感谢,看来offsetof的确属于诡计。。。还是只用编译器的实现吧!

论坛徽章:
0
156 [报告]
发表于 2011-09-29 16:21 |只看该作者
4)volitale的含义吧?
rain_fish 发表于 2010-03-18 09:32


    ……volatile

论坛徽章:
0
157 [报告]
发表于 2011-09-30 11:14 |只看该作者
xuexile

论坛徽章:
0
158 [报告]
发表于 2011-09-30 14:43 |只看该作者
cjaizss 神人, 受教中。。。 {:3_183:}

论坛徽章:
0
159 [报告]
发表于 2011-09-30 15:02 |只看该作者
5:OFFSETOF(s, m)的宏定义,s是结构类型,m是s的成员,求m在s中的偏移量。
#defien OFFSETOF(s, m) ((uint32_t) & ((s*)0) -> m)

论坛徽章:
0
160 [报告]
发表于 2011-09-30 15:11 |只看该作者
cjaizss很牛逼啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP