在 C 和 C++ 中,void 类型和 sizeof 运算符是每位程序员都应掌握的基本概念。然而,sizeof(void) 的概念可能会让人感到困惑,特别是对于这些语言的新手来说。本文将解释 void 是什么,为什么 sizeof(void) 在传统意义上没有意义,以及这些概念在实际编程中的应用。
什么是void
在 C 和 C++ 中,void是用于表示不存在任何类型的关键字。它通常用于三种场景。。
函数
当某个函数的返回值被声明为void,即意味着该函数不返回任何内容,那么获取函数返回内容的操作将是非法或者未定义的行为。
在这个函数中,只有一行输出操作,不返回任何类型。
空指针
空指针void( void *) 是一种特殊类型的指针,可以指向任何数据类型。但是,由于未指定类型,因此在解引用之前必须将其转换为适当的类型。
函数参数
相信很多从事C开发的人,经常会见到形如fun(void)这种代码,在这种代码中,void作为函数参数的意思是该函数没有参数,或者说指定函数不接受任何参数,与fun()等同,不过这种写法现在已经很少见了~
sizeof操作符
在 C++ 中,sizeof 操作符是一个编译时运算符,用于获取数据类型或对象的内存大小。它是一个非常重要的工具,可以帮助程序员了解变量、类型或数据结构的内存占用情况。
sizeof(void)
好了,前面的一系列铺垫,就是为了引入本节主题。
对于这种问题,我一般会先在本地编码试试。
// size.c
以及
// size.cc
对于size.c,尝试使用gcc和clang进行编译:
输出都是
但是,对于size.cc即对于c++版本的,g++可以编译通过,输出同c版本,而clang++则编译失败,输出如下:
说实话,看到编译和运行结果的时候,我是一脸懵的,完全出乎了我的意料~
针对上面的结果,看了某些资料,偶然翻到了标准对这块的回复(ISO/IEC 9899:2011):
意思是sizeof操作符不得应用于以下情况的表达式:
• 函数类型的表达式
• 不完整类型的表达式
• 这种类型的带括号的名称
• 指定位域成员的表达式
以及:
意思是void是一个不完整类型,那么问题来了,既然标准都说了void是一个不完整类型,那么gcc为什么输出为1呢?
针对这个问题,继续查资料,得到回复如下:
意思是,在 GNU C中,指向 void 指针和指向函数的指针支持加法和减法操作。这是通过将 void 或函数的大小视为1来实现的。
因此,sizeof 操作符也可以用于 void 和函数类型,并返回 1。选项 -Wpointer-arith 会在使用这些扩展时发出警告。