电子产业一站式赋能平台

PCB联盟网

搜索
查看: 175|回复: 0
收起左侧

sizeof(void)之谜

[复制链接]

498

主题

498

帖子

4895

积分

四级会员

Rank: 4

积分
4895
发表于 2024-10-16 09:02:00 | 显示全部楼层 |阅读模式
最近有小伙伴说没有收到当天的文章推送,这是因为微信更改了推送机制,导致没有星标公众号的小伙伴刷不到当天推送的文章,无法接收到一些比较实用的知识和资讯。所以建议大家加个星标??,以后就能第一时间收到推送了。

fdx1x4hmkpb6405737111.png

fdx1x4hmkpb6405737111.png


在 C 和 C++ 中,void 类型和 sizeof 运算符是每位程序员都应掌握的基本概念。然而,sizeof(void) 的概念可能会让人感到困惑,特别是对于这些语言的新手来说。本文将解释 void 是什么,为什么 sizeof(void) 在传统意义上没有意义,以及这些概念在实际编程中的应用。
什么是void?在 C 和 C++ 中,void是用于表示不存在任何类型的关键字。它通常用于三种场景。
函数当某个函数的返回值被声明为void,即意味着该函数不返回任何内容,那么获取函数返回内容的操作将是非法或者未定义的行为。
void Print() {
  std::cout "Hello world!!!" 在这个函数中,只有一行输出操作,不返回任何类型。
空指针空指针void( void *) 是一种特殊类型的指针,可以指向任何数据类型。但是,由于未指定类型,因此在解引用之前必须将其转换为适当的类型。
void* ptr;
int num = 42;
ptr = # // void 指针可以指向 int 类型的地址
int* intPtr = (int*)ptr; // 需要将 void 指针转换为具体类型函数参数相信很多从事C开发的人,经常会见到形如fun(void)这种代码,在这种代码中,void作为函数参数的意思是该函数没有参数,或者说指定函数不接受任何参数,与fun()等同,不过这种写法现在已经很少见了~
void fun(void) {
    // 函数体
}sizeof操作符在 C++ 中,sizeof 操作符是一个编译时运算符,用于获取数据类型或对象的内存大小。它是一个非常重要的工具,可以帮助程序员了解变量、类型或数据结构的内存占用情况。
int x = 10;
printf("size of int: %d bytes
", sizeof(int));
printf("size of x: %d bytes
", sizeof(x));sizeof(void)好了,前面的一系列铺垫,就是为了引入本节主题。
对于这种问题,我一般会先在本地编码试试。
// size.c
#include
int main() {
  printf("sizeof void is %d bytes
", sizeof(void));
  return 0;
}以及
// size.cc
#include
int main() {
  std::cout "sizeof void is: " sizeof(void) return 0;
}对于size.c,尝试使用gcc和clang进行编译:
clang size.c -o size // clang
gcc size.c -o size // gcc输出都是
sizeof void is 1 bytes但是,对于size.cc即对于c++版本的,g++可以编译通过,输出同c版本,而clang++则编译失败,输出如下:
size.cc:4:38: error: invalid application of 'sizeof' to an incomplete type 'void'
    4 |   std::cout 说实话,看到编译和运行结果的时候,我是一脸懵的,完全出乎了我的意料~
针对上面的结果,看了某些资料,偶然翻到了标准对这块的回复(ISO/IEC 9899:2011):
The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member.
意思是sizeof 操作符不得应用于以下情况的表达式:
?函数类型的表达式?不完整类型的表达式?这种类型的带括号的名称?指定位域成员的表达式
以及:
The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.
意思是void是一个不完整类型,那么问题来了,既然标准都说了void是一个不完整类型,那么gcc为什么输出为1呢?
针对这个问题,继续查资料,得到回复如下:
In GNU C, addition and subtraction operations are supported on pointers to void and on pointers to functions. This is done by treating the size of a void or of a function as 1.
A consequence of this is that sizeof is also allowed on void and on function types, and returns 1.
The option -Wpointer-arith requests a warning if these extensions are used.
意思是,在 GNU C中,指向 void 指针和指向函数的指针支持加法和减法操作。这是通过将 void 或函数的大小视为1来实现的。
因此,sizeof 操作符也可以用于 void 和函数类型,并返回 1。选项 -Wpointer-arith 会在使用这些扩展时发出警告
——EOF——日常分享C/C++、计算机学习经验、工作体会,欢迎点击此处查看我以前的学习笔记&经验&分享的资源。
我组建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起进群交流。

ui5mlezdxb26405737211.png

ui5mlezdxb26405737211.png

欢迎你添加我的微信,我拉你进技术交流群。此外,我也会经常在微信上分享一些计算机学习经验以及工作体验,还有一些内推机会。

l1imkzljp146405737311.png

l1imkzljp146405737311.png

加个微信,打开另一扇窗
经常遇到有读者后台私信想要一些编程学习资源,这里分享 1T 的编程电子书、C/C++开发手册、Github上182K+的架构路线图、LeetCode算法刷题笔记等精品学习资料,点击下方公众号会回复"编程"即可免费领取~
感谢你的分享,点赞,在看三  

nthatp2qzek6405737411.gif

nthatp2qzek6405737411.gif

回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表