C和C++代码之间的不兼容问题

17

给定的 C 代码

#include <stdio.h>
int x = 14; 
size_t check()
{
   struct x {};
   return sizeof(x); // which x
}
int main()
{
    printf("%zu",check()); 
    return 0;
}

在我的32位C实现中输出4,而在C++中该代码

#include <iostream>
int x = 14;    
size_t check()
{
   struct x {};
   return sizeof(x); // which x    
}
int main()
{
    std::cout<< check(); 
    return 0;
}

输出为1。为什么会有这样的差异?


1
可能的重复问题:https://dev59.com/x3A75IYBdhLWcg3wJFcL https://dev59.com/jnVD5IYBdhLWcg3wAWoO - phooji
2
@phooji:不,那不是重复的。 - Saurabh Manchanda
@Saurabh:你可能是对的——这些问题并不完全涵盖相同的内容,但我认为答案是相关的(请参见Prasoon的答案以及我对你的答案的评论)。 - phooji
3个回答

26
在C++类声明中,struct x {};引入名称 xcheck的作用域中,并隐藏之前在文件作用域中声明为的变量x。你会得到1作为输出,因为在C ++中,空类的大小不能为零
在C语言中,结构体标签名称的内部作用域声明永远不会隐藏外部作用域中对象或函数的名称。您需要使用标记名称:struct来引用类型名称x(结构体)。但是,你不能在C中有一个空结构体,因为它违反了对结构体的语法限制(然而gcc支持它作为一种扩展)。

6
+1,但也许应该强调一个事实,即在C ++中,struct x只隐藏变量,因为x在外部作用域中声明。如果它们在同一作用域中声明,它们将愉快地共存,并且sizeof的行为与C相同。 - Jens Gustedt

8

这段 C 代码给出了全局变量 'x' 的大小,而 C++ 代码则给出了空结构体的大小。如果要获取 C 代码中结构体 x 的大小,请使用 sizeof(struct x)。


你对作用域问题的看法是正确的,但这并不是全部。特别是,现在问题变成了:为什么C版本中sizeof(struct x)的结果为0 :) - phooji
@phooji:在C中,空的结构体是一个约束违规。 - Prasoon Saurav
1
@phooji:由于C语言不允许空结构体,因此上面程序中的结构体定义是无效的,我认为就此争论并没有太大好处。 - Saurabh Manchanda

7
在C语言中,结构体标签位于一个单独的命名空间中,你必须使用struct关键字来访问其中的名称。这就是为什么“typedef struct {} x”惯用语在C语言中非常流行的原因——它允许你将结构体名称提升到全局命名空间中。
相比之下,在C++中,结构体(和所有其他名称)存在于声明周围的命名空间中,而不是像C语言中那样存在于单独的结构体标签命名空间中。
正如Saurabh所说,在C语言中使用sizeof(struct x),或者使用“typedef struct {} x”技巧来使sizeof(x)在C++中也能工作。
作为额外的奖励,C++程序输出1,因为具体的类对象必须具有非零大小(以便不同的对象必须具有不同的地址),所以编译器已经用匿名char值填充了结构体。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接