免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1677 | 回复: 7
打印 上一主题 下一主题

[C] The Standard C Library 的一个问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-10-01 11:32 |只看该作者 |倒序浏览
p79的问题, #if (-1 + 0x0) >> 1 > 0x7fff 不知是如何确定大于16位的,我用VC测试#if (-1 + 0x0) >> 1 > 0x7fff
结果为假.


The presence of <limits .h> is also designed to discourage an old programming
trick that is extremely nonportable. Some programs attempted
to test the properties of the execution environment by writing #if directives:

#if (-1 + 0x0) >> 1 > 0x7fff
/* must have ints greater than 16 bits */
...
#endif

This code assumes that whatever arithmetic the preprocessor performs
is the same as what occurs in the execution environment. Those who deal
heavily with cross compilers know well that the translation environment
can differ markedly from the execution environment. For tricks like this
one to work, theC Standard would have to require that the translator mimic
the execution environment very closely. And translator families with a
common front end would have to adapt translation-time arithmetic to suit
each environment.

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
2 [报告]
发表于 2012-10-01 11:43 |只看该作者
本帖最后由 starwing83 于 2012-10-01 11:44 编辑

这是有符号数。右移是否是算术右移是符号实现定义的。

应该这样:

#if -1u >>1 == 0x7fff

但是问题是,cpp不一定支持u后缀(我也不知道),而且cpp的integer-literal也不一定会和C的int类型相同。最简单的方法是

#if INT_MAX > 32770

稍微大一点点,免得出意外……

人家原文就指出这个方法了,即limits.h这个标准头文件,现在这个时代没有这个头文件的编译器已经找不到,所以放心地用吧。

论坛徽章:
0
3 [报告]
发表于 2012-10-01 11:59 |只看该作者
我知道应该使用limits.h这个标准头文件.

我的具体问题在于原来的背景下这个表达式怎么起作用的,我在VC 6.0 不起作用 .

  -1u >>1 == 0x7fff  对我来说不是问题, 但是原来加0x0的动机是什么.  (-1 + 0x0) 为什么成了unsigned类型

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
4 [报告]
发表于 2012-10-01 12:09 |只看该作者
The presence of <limits .h> is also designed to discourage an old programming
trick that is extremely nonportable
. Some programs attempted
to test the properties of the execution environment by writing #if directives:

说了这种方法极端不可移植,所以现在不成立也正常。

很有可能是integer promotion之类的,有可能古代某些编译器的16进制常量是unsigned,这很自然吧?根据而且也许他们规定了整型提升(当然和现在定义的不一样),int+unsigned == unsigned,最终就成了unsigned的-1了。当时可能是没有数字后缀才这样,毕竟这玩意儿是标准提出来的,出现年代较晚。

但是这个规则现在肯定没有了。所以你试不出来。

论坛徽章:
0
5 [报告]
发表于 2012-10-01 12:14 |只看该作者
似乎有道理,谢谢,我再查证一下

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
6 [报告]
发表于 2012-10-01 12:29 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
7 [报告]
发表于 2012-10-01 12:31 |只看该作者
回复 6# pmerofc


    如果int是16位,那么最大就应该是2^15-1即32767,为了安全起见加了3,就是32770,不过也许加2就行了,Lua的头文件里面用的是:


/* avoid overflows in comparison */
#if INT_MAX-20 < 32760                /* { */
#define LUAI_BITSINT        16
#elif INT_MAX > 2147483640L        /* }{ */
/* int has at least 32 bits */
#define LUAI_BITSINT        32
#else                                /* }{ */
#error "you must define LUA_BITSINT with number of bits in an integer"
#endif                                /* } */


额……这个更保险一点,防止32770超过了int的长度导致不测……恩,Lua的质量是没的说的~

论坛徽章:
2
CU大牛徽章
日期:2013-04-17 11:46:28CU大牛徽章
日期:2013-04-17 11:46:39
8 [报告]
发表于 2012-10-02 09:04 |只看该作者
呵呵....
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP