声明,初始化,C中的说明

时间:2017-07-12 10:04:35

标签: c

我正准备参加关于C编程的考试,并遇到了以下问题,我不知道如何回答:

"给出了以下语法正确的声明。假设所有变量都已在后续指令中初始化:

void *vptr, *wptr;
char *s;
size_t vsize, ssize;
int cmp;

其中三条指令在语义上是不正确的,会导致编译错误,即:?:

  1. vptr++;
  2. cmp = vptr == wptr;
  3. vsize = sizeof(*vptr);
  4. s = wptr;
  5. s = vptr - 1;
  6. vptr = malloc(ssize * sizeof *s);
  7. 当我尝试编译这些(使用gnu编译器)时,我从来没有得到错误。然而,我的猜测是3,5和6是不正确的,因为我试图获得void(3)的大小,访问/分配尚未分配的内存(5)并分配内存而不释放先前的内存(6)。我不太确定我的答案,而且我不明白为什么汇编对所有这些说明都很好。有人有解释吗?

3 个答案:

答案 0 :(得分:4)

几乎正确。

错误的是(a),(c)和(e)(1,3,5,编辑后)。

所有这些的解释基本相同:(a)和(e)执行指针算术,这在void *上是不可能的,因为void未知且没有一个大小。 (c)类似,sizeof()被赋予void表达式,void也没有大小。

答案 1 :(得分:2)

错误的是:1,3,5因为

void*上的算术在C和C ++中都是非法的。

来自标准:

  

6.5.6-2:另外,两个操作数都应具有算术类型,或者一个操作数应是指向对象类型的指针,   其他应具有整数类型

     

6.2.5.1:类型被划分为对象类型(完全描述对象的类型),函数类型(描述函数的类型),   和不完整的类型(描述对象但缺乏信息的类型)   需要确定它们的尺寸。)

     

6.2.5-19:void类型包含一组空值;这是一个不完整的类型,无法完成

void不完整(转换为,编译器不知道其大小),因此6.5.6-2不能在上述表达式中使用它。

答案 2 :(得分:1)

vptr++

是不正确的,因为vptr是指向未知大小的对象的指针,因此该表达式将在vptr+=sizeof(*vptr)中被删除,*vptr的类型为空; sizeof(void)未定义,因为类型不完整。 gcc考虑sizeof(void)=sizeof(char)=1,但这是gnu扩展名。

vsize = sizeof(*vptr);

不正确,因为*vptr的类型为void,如上所述。

s = vptr - 1;

也是不正确的,因为指针算术意味着减去sizeof (typeof(*vptr))