C中的严格类型指针(假设)

时间:2011-03-26 13:52:52

标签: c pointers

这是我今天参加考试的一个问题:

在C中,假设指针是严格类型的(即,指向int的指针不能用于指向char)。这是否会降低其表现力?如果不是,为什么以及如何补偿这种限制?如果有,怎么样?还有什么更多的结构可以用来“均衡”C的表达能力的丧失?

其他一些细节:

  • 通过降低表现力,我认为这意味着:你将无法创建早期的某些程序。
  • 严格键入指针意味着您无法执行以下操作:int x = 5; int *p = &x; char *temp = (char*)p;
  • 这包括(void*)次转化

我也在下面提到了我的答案。

8 个答案:

答案 0 :(得分:5)

这是否意味着不再有void*?如果是,那么是:C的表达力将是有限的,因为malloc将无法实现。您需要在C ++ new的精神中添加一个新的,类型化的免费商店分配机制。

(或者,否:C仍然是Turing-complete。但我不认为这就是这里的含义。)

实际上,C甚至没有图灵完备;见下面的评论。

答案 1 :(得分:2)

它实际上可能会提高C的表现力。 C是指定任何给定实现的少数语言之一不完整。标准中的类型表示将所有类型指定为char的重叠数组,表示所有类型和程序可用的总数据(所有可能指针的空间,所有可能的文件名,以及所有可能的文件偏移量等是有限约束的,因此C的计算模型是有限状态机

如果删除了指针被表示为char [sizeof (pointer type)]的要求,那么正式指定的语言原则上可以处理无限量的数据,并且它将是图灵完备的。

答案 2 :(得分:1)

这是一个非常主观的问题。认为事实上我不知道“表达能力”是什么;)

仍然无法在指针类型之间进行转换是我头脑中的一大限制。似乎在使用Java映射时,char数组(例如来自网络套接字之类的东西)到类是非常烦人的。只需将其转换并重新解释内存的能力非常有用,并且可以在处理随机内存块时进行大量优化。

你如何解决这些限制?也许实现一个“强制转换”功能,或者只是一个可以重新解释内存的模板化memcpy函数,对于优化,对于像我这样的人来说,生产力是一个巨大的好处。它甚至可能是允许某种类“id”包含在字节流中的计划,以便您知道它可以被重新解释为特定的类。

拥有这种能力的缺点是它允许您以完全错误的方式解释数据。这可能会导致非常讨厌的错误。

答案 3 :(得分:1)

这个问题类似于询问指针强制转换的有用/有效用途。以下是一些:

如果没有指针强制转换,您必须拥有多个版本的memcpymemmovemalloc,因为这些版本都需要实现和使用指针转换。在malloc的情况下,为用户定义的struct分配内存变得不可能。

在稍微不同的类别中,您无法实现多态qsort(标准库提供的那个对void*数组进行排序,并且可以有效地用于对各种指针的数组进行排序)

关于什么样的功能可以重新获得表达能力,一个识别多态的类型系统,这样你就不必用不安全的指针转换编码它将是一个很好的步骤。 Languages of the ML family已经有了这种类型系统很长一段时间,如果你熟悉Java's generics,他们就会遵循同样的思路。

答案 4 :(得分:1)

我认为它不会降低它的表现力 - 你仍然可以写一个图灵机翻译,这意味着图灵完成了。例如,请参阅此code golf thread

如果你的意思是在用户方便性方面具有表现力,那么它肯定会限制C很多,因为内存分配机制(malloc& co。)必须改变。

答案 5 :(得分:0)

  

在C中,假设指针是   严格键入(即指向   int不能用于指向a   炭)。

在C语言中提倡严格的指针输入完全失去了情节,这只是汇编语言的便携式简写。你认为能够射击自己,一个优秀的开发人员将足够聪明,不会。

答案 6 :(得分:0)

我想到了一种解决不能在各种类型之间进行类型转换的限制的方法。你可以使用一个联盟:

union alltypepointers  
{  
    char* c,  
    short* s,
    int* i,  
    float* f,
    double* d,
    ...
};  

所有指针的大小都相同,因此如果您更改了一个指针,则可以将其读取为任何其他类型。你也可以对这些指针进行算术运算:

int variable = 0x2345;
alltypepointers p;
p.i = &variable;
char *temp = p.c;
p.c++;
int newint=*p.i;

所以,你仍然可以做你之前可以做的所有事情=>表现力没有下降。

答案 7 :(得分:-3)

(someType *)((void *)somePtr)

该构造允许您将任何指针转换为(someType *)。