我正准备参加关于C编程的考试,并遇到了以下问题,我不知道如何回答:
"给出了以下语法正确的声明。假设所有变量都已在后续指令中初始化:
void *vptr, *wptr;
char *s;
size_t vsize, ssize;
int cmp;
其中三条指令在语义上是不正确的,会导致编译错误,即:?:
vptr++;
cmp = vptr == wptr;
vsize = sizeof(*vptr);
s = wptr;
s = vptr - 1;
vptr = malloc(ssize * sizeof *s);
当我尝试编译这些(使用gnu编译器)时,我从来没有得到错误。然而,我的猜测是3,5和6是不正确的,因为我试图获得void(3)的大小,访问/分配尚未分配的内存(5)并分配内存而不释放先前的内存(6)。我不太确定我的答案,而且我不明白为什么汇编对所有这些说明都很好。有人有解释吗?
答案 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))
。