标准C

时间:2015-12-23 18:48:29

标签: c pointers language-lawyer c99 c11

我在这个网站上已经阅读了几个关于这个主题的问题,但我仍然有疑问。

在标准C中,我们可以阅读:

  

6.3.2.3.p.5:整数可以转换为任何指针类型。 [...]
  6.3.2.3.p.6:任何指针类型都可以转换为整数类型。 [...]。

省略的文本(将放在括号[...]中)只讨论转换失败时可能发生的问题。

但是我的问题更为笼统:

  1. 我观察到整数数学数是无限的一组值。
  2. C中的任何整数类型只能表示整数数学值的有限子集。
  3. 在第6.3.2.3.p5 / p6段中,似乎标准C11 假定“每个指针值都可以映射到整数数学值”。
  4. 此外,编辑C11标准的方式似乎只是当这个数学(或抽象)值无法用开发者选择的预期整数类型表示时,无论出于何种原因,是操作失败的时候。
  5. 我的问题是:是我的解释(3。)正确吗?

    另一方面,当我们定义一个大小为 N T 类型的数组时,
    因为我们可以对数组的位置进行整数运算,
    结果很明显,至少在“本地”级别,在数组中, 我们有相应的数组内存行为 同样地,算术上,也就是说,从 0 N-1 的数字集合。

    通过定义数组或分配的对象,我们可以确定,在C中, 存储器地址可以被“局部地”视为算术上等于整数的子集。

    然而,这种“本地”行为不足以得出结论 标准C假设一个内存模型,其内存地址可以被视为“只有一个同一组整数”的一部分。

    然而,6.3.2.3.p5 / p6似乎“暗示”这个更强有力的断言,尽管我并不完全确定。

    另一个问题可能会带来更多亮点:

    • 在标准C中打开两个不同有效指针pq(即:p != q)的可能性,当转换为整数类型时,结果整数值变为的等于即可。

3 个答案:

答案 0 :(得分:5)

奇怪的是,你忽略了部分标准,“只是谈论转换失败时可能发生的问题”,其中一些正是解决你问题的部分。

  
      
  1. 我观察到整数数学数字是无穷大的一组值。
  2.   

是的,但无关紧要。标准说“任何指针类型都可以转换为[任意]整数类型”(强调添加)。它特指一系列C数据类型,包括但不限于int。您在引用中省略的文本清楚地表明某些整数类型可能无法表示结果。实际上,它说“结果不必在任何整数类型”的值范围内(强调添加)。

  
      
  1. C中的任何整数类型只能表示整数数学值的有限子集。
  2.   

真。

  
      
  1. 在第6.3.2.3.p5 / p6段中,似乎标准C11假定“每个指针值都可以映射到整数数学值”。
  2.   

不,事实上不是。你省略的部分文字是“ 结果是实现定义的“用于双向转换,但有一些例外。这种转换的实现定义行为可能是程序退出。我接受标准表明可能存在映射或映射,例如你描述,但不是假设有一个。

  
      
  1. 此外,编辑C11标准的方式似乎表明,只有当这个数学(或抽象)值无法在开发人员选择的整数类型中表示时,无论出于何种原因,都是在操作失败时。 / LI>   

操作永远不会失败。在许多情况下,行为是实现定义的,在某些情况下它是未定义的,但这完全不同。

但请注意,该标准对选择提供可选intptr_t和/或uintptr_t类型的实现提出了更多要求,因为这些要求支持往返,保值{{1} }到整数类型到void *次转换。此类实现(通常)必须具有从所有可能指针值的1-1映射,不仅是数学整数,还有可表示的整数值。

答案 1 :(得分:2)

  

我的问题是:我在第(3)点的解释是否正确?

标准指定类型uintptr_tintptr_t,以便每个有效指针可以转换为uintptr_t / intptr_t并再次返回。比较ISO 9899:2011§7.20.1.4:

  

7.20.1.4能够保存对象指针的整数类型

     

1以下类型指定一个带符号的整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将等于原始指针:

intptr_t
     

以下类型指定一个无符号整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将与原始指针进行比较:

uintptr_t
     

这些类型是可选的。

但这些类型可能不存在,在这种情况下,不保证每个指针都映射到一个整数。

  

在标准C中打开两个不同有效指针p,q的可能性(即:p!= q),当转换为整数类型时,得到的整数值变得相等。

是的,这可能发生。考虑像8086那样具有20位指针和16位int的平台。显然,在将指针转换为整数时,许多指针将被映射到同一个整数。如果你采用更大的类型,比如32位long,那么你会得到每个指针的唯一值。

答案 2 :(得分:1)

第{6}条[...]部分给出了p != q问题的答案:

  

如果结果无法以整数类型表示,则表现为行为   未定义。

因此,如果pq是两个不同的有效指针,并且您将这些指针转换为整数而不调用未定义的行为,则生成的整数将不会比较相等

主要问题的答案见附注67(适用于第5段):

  

用于将指针转换为整数或。的映射函数   整数到指针的目的是与寻址一致   执行环境的结构。

在我所知道的每个执行环境中,寻址结构基于自然数的有限子集,其中0用作NULL指针。因此,如果整数值范围超出目标硬件中使用的地址范围,则保证从指针转换为整数类型。