为什么C允许不兼容的指针类型之间的转换?

时间:2012-06-24 06:58:01

标签: c99

我想知道为什么C99允许不兼容的指针类型之间的转换:

void f(int* p)
{
}

void c(char* p)
{
   f(p);
}

C11是否也允许这些?是否需要符合实施来诊断此类转换?

2 个答案:

答案 0 :(得分:1)

C99不允许在不同类型的指针之间进行隐式转换(除了void*之外)。这就是C99理由所说的:

  

将指向任何类型对象的指针转换为指向不同类型对象的指针而无需显式转换是无效的。

这是赋值规则的结果,其约束条件是以下之一应该成立(当涉及指针时)(C99 6.5.16.1“简单赋值”):

  
      
  • 两个操作数都指向兼容类型的限定或非限定版本的指针,左边指向的类型具有全部   右边指出的类型的限定符;
  •   
  • 一个操作数是指向对象或不完整类型的指针,另一个操作数是指向void的限定或非限定版本的指针,并且   左边指向的类型具有该类型的所有限定符   右边指出;
  •   
  • 左操作数是指针,右边是空指针常量
  •   

将指针作为参数传递给prototyped函数遵循相同的规则,因为(C99 6.5.2.2/7“函数调用”):

  

如果表示被调用函数的表达式具有类型   确实包含一个原型,参数被隐式转换为   如果通过赋值,则为相应参数的类型

C90和C11都有类似的措辞。

我相信许多编译器(包括GCC)放宽了这个约束,只发出一个警告,因为有太多的遗留代码依赖于它。请注意,void*是ANSI C标准的一项发明,因此预标准,可能很多标准后的代码通常使用char*int*作为'通用'指针类型。

答案 1 :(得分:0)

没有“不兼容”的指针类型。

C的优点在于它允许程序员做他们想做的事。由程序员决定哪些是兼容的和不兼容的。声称强制“class”或“type”凝聚力的其他语言以有限的方式这样做。在允许引用对象的那一刻,使用了指针,并且可以启动类管理不善。