免费注册 查看新帖 |

Chinaunix

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

[C] 判断是16位机还是32位机,不用sizeof [复制链接]

论坛徽章:
0
1 [报告]
发表于 2007-11-28 22:05 |显示全部楼层
>> 系统位数不一定等于sizeof(int)。

是这样的。所以即使得到了 int 的长度是 32 位,也不能说机器一定就是 32 位的。

>> 楼上的这几位难道不知道,对于一个非法指针进行加减运算根本就是错误的C程序?

指针不存在什么非法与合法的问题,但是有有效和无效之区分——如果指针指向一个有效的对象,指针是有效的,也就是说可以通过指针的间接运算来访问指向的对象。

对于指针的加减法运算,要保证运算前和运算后的指针指向同一个数组对象或者结尾元素的后面,否则结果是无定义的。单个对象可以看作是长度为 1 的数组,所以求解 sizeof(int) 可以这样实现:
  1. int m;
  2. /* sizeof(int ) = (char*)(&m + 1) - (char*)&m */
复制代码


>> 只要不取(指针的)内容,就是合法.

这种说法不正确。参见前面对指针加减法的说明。

>> offsetof就这样干的

很多实现中的 offsetof 都实际上引用了 NULL 指针(空指针)。一般来说引用空指针是无定义的行为。

由于 offsetof 的实现是跟随编译器来的,编译器保证了这种实现结果不是未定义的。然而,如果在你的程序中定义 offsetof,则其结果是未定义的。也就是说:offsetof 只能由编译器(标准库)提供,而不能由用户自己定义实现。

论坛徽章:
0
2 [报告]
发表于 2007-11-28 22:43 |显示全部楼层
原帖由 Godbach 于 2007-11-28 22:34 发表
多谢斑竹啊,如果这样的话,程序应该如何实现呢


一般来说,操作系统最清楚它运行之上的硬件环境了。可在程序中使用操作系统提供的功能或者检测结果。

论坛徽章:
0
3 [报告]
发表于 2007-12-02 14:31 |显示全部楼层
原帖由 Edengundam 于 2007-11-29 09:45 发表



C99标准允许对指针进行加法和减法的运算.

6.5.6 Additive operators

When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the point ...


>> C99标准允许对指针进行加法和减法的运算.

这固然不错。但是不能据此说指针运算的结果一定是正确的。

>> When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand.

就像整数除以整数的结果仍然是整数类型一样,这并不是说除数为 0 的情况下结果是有定义的。

>> 关于指向数组成员的指针来说, 去解引用才受到限制.

解引用固然受此限制,那么引文中“otherwise, the behavior is undefined.” 中的“otherwise” 指的情况呢?不正是我在上面提到的情况吗?

论坛徽章:
0
4 [报告]
发表于 2007-12-02 15:22 |显示全部楼层
原帖由 Edengundam 于 2007-12-2 15:13 发表


红色这句是上下文. 根本没有提到如果指针不是这种情况下的定义.  脱离这句话otherwise就没意义了, 我没有看到其他地方关于在指向任意地址上进行加减操作的定义, 既没有规定"未定义", 也没有"非法".


如果不好理解的话,建议看看 C99 标准的 J.2 Undefined behavior 的下面这句话,说得更明白些:

(The behavior is undefined in the following circumstances

— Addition or subtraction of a pointer into, or just beyond, an array object and an
integer type produces a result that does not point into, or just beyond, the same array
object (6.5.6).

论坛徽章:
0
5 [报告]
发表于 2007-12-02 16:25 |显示全部楼层
If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.

上面说的是 P + N 情况。这里 P 是指针,N 是整数。上文翻译如下:

如果指针操作数(P)和结果(P + N)都指向同一数组对象的元素或者(不是数组元素的)次数组对象最后一个元素的下一个位置,(对 P + N 的)求值不应产生溢出;否则,其行为是未定义的。如果结果(P + N)指向数组对象最后一个元素的下一个位置,它不应该用作用来进行求值的单目运算符 * 的操作数。

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

(The behavior is undefined in the following circumstances:)

— Addition or subtraction of a pointer into, or just beyond, an array object and an
integer type produces a result that does not point into, or just beyond, the same array
object (6.5.6).

翻译如下:

(下列情况属于未定义行为:)

— 如果一个指针指向数组对象或者数组对象最后一个元素的下一个位置,而对此指针加上或者减去一个整数类型产生的结果既不指向同一数组数组对象,也不指向(同一数组对象的)最后一个元素的下一个位置

论坛徽章:
0
6 [报告]
发表于 2007-12-02 16:31 |显示全部楼层
>> 没错, 但是这些都是特指数组对象的指针.
>> 如果指针没有指向数组对象, 这些规则都不管用.

不是这样的。还是看看标准是怎么规定的吧:

6.5.6-7 For the purposes of these operators, a pointer to an object that is not an element of an
array behaves the same as a pointer to the first element of an array of length one with the
type of the object as its element type.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP