電子產(chǎn)業(yè)一站式賦能平臺(tái)

PCB聯(lián)盟網(wǎng)

搜索
查看: 80|回復(fù): 0
收起左側(cè)

sizeof(void)之謎

[復(fù)制鏈接]

445

主題

445

帖子

3456

積分

四級(jí)會(huì)員

Rank: 4

積分
3456
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-10-16 09:02:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
最近有小伙伴說(shuō)沒(méi)有收到當(dāng)天的文章推送,這是因?yàn)槲⑿鸥牧送扑蜋C(jī)制,導(dǎo)致沒(méi)有星標(biāo)公眾號(hào)的小伙伴刷不到當(dāng)天推送的文章,無(wú)法接收到一些比較實(shí)用的知識(shí)和資訊。所以建議大家加個(gè)星標(biāo)??,以后就能第一時(shí)間收到推送了。


在 C 和 C++ 中,void 類(lèi)型和 sizeof 運(yùn)算符是每位程序員都應(yīng)掌握的基本概念。然而,sizeof(void) 的概念可能會(huì)讓人感到困惑,特別是對(duì)于這些語(yǔ)言的新手來(lái)說(shuō)。本文將解釋 void 是什么,為什么 sizeof(void) 在傳統(tǒng)意義上沒(méi)有意義,以及這些概念在實(shí)際編程中的應(yīng)用。
什么是void?在 C 和 C++ 中,void是用于表示不存在任何類(lèi)型的關(guān)鍵字。它通常用于三種場(chǎng)景。
函數(shù)當(dāng)某個(gè)函數(shù)的返回值被聲明為void,即意味著該函數(shù)不返回任何內(nèi)容,那么獲取函數(shù)返回內(nèi)容的操作將是非法或者未定義的行為。
void Print() {
  std::cout "Hello world!!!" 在這個(gè)函數(shù)中,只有一行輸出操作,不返回任何類(lèi)型。
空指針空指針void( void *) 是一種特殊類(lèi)型的指針,可以指向任何數(shù)據(jù)類(lèi)型。但是,由于未指定類(lèi)型,因此在解引用之前必須將其轉(zhuǎn)換為適當(dāng)?shù)念?lèi)型。
void* ptr;
int num = 42;
ptr = # // void 指針可以指向 int 類(lèi)型的地址
int* intPtr = (int*)ptr; // 需要將 void 指針轉(zhuǎn)換為具體類(lèi)型函數(shù)參數(shù)相信很多從事C開(kāi)發(fā)的人,經(jīng)常會(huì)見(jiàn)到形如fun(void)這種代碼,在這種代碼中,void作為函數(shù)參數(shù)的意思是該函數(shù)沒(méi)有參數(shù),或者說(shuō)指定函數(shù)不接受任何參數(shù),與fun()等同,不過(guò)這種寫(xiě)法現(xiàn)在已經(jīng)很少見(jiàn)了~
void fun(void) {
    // 函數(shù)體
}sizeof操作符在 C++ 中,sizeof 操作符是一個(gè)編譯時(shí)運(yùn)算符,用于獲取數(shù)據(jù)類(lèi)型或?qū)ο蟮膬?nèi)存大小。它是一個(gè)非常重要的工具,可以幫助程序員了解變量、類(lèi)型或數(shù)據(jù)結(jié)構(gòu)的內(nèi)存占用情況。
int x = 10;
printf("size of int: %d bytes
", sizeof(int));
printf("size of x: %d bytes
", sizeof(x));sizeof(void)好了,前面的一系列鋪墊,就是為了引入本節(jié)主題。
對(duì)于這種問(wèn)題,我一般會(huì)先在本地編碼試試。
// 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;
}對(duì)于size.c,嘗試使用gcc和clang進(jìn)行編譯:
clang size.c -o size // clang
gcc size.c -o size // gcc輸出都是
sizeof void is 1 bytes但是,對(duì)于size.cc即對(duì)于c++版本的,g++可以編譯通過(guò),輸出同c版本,而clang++則編譯失敗,輸出如下:
size.cc:4:38: error: invalid application of 'sizeof' to an incomplete type 'void'
    4 |   std::cout 說(shuō)實(shí)話,看到編譯和運(yùn)行結(jié)果的時(shí)候,我是一臉懵的,完全出乎了我的意料~
針對(duì)上面的結(jié)果,看了某些資料,偶然翻到了標(biāo)準(zhǔn)對(duì)這塊的回復(fù)(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 操作符不得應(yīng)用于以下情況的表達(dá)式:
?函數(shù)類(lèi)型的表達(dá)式?不完整類(lèi)型的表達(dá)式?這種類(lèi)型的帶括號(hào)的名稱(chēng)?指定位域成員的表達(dá)式
以及:
The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.
意思是void是一個(gè)不完整類(lèi)型,那么問(wèn)題來(lái)了,既然標(biāo)準(zhǔn)都說(shuō)了void是一個(gè)不完整類(lèi)型,那么gcc為什么輸出為1呢?
針對(duì)這個(gè)問(wèn)題,繼續(xù)查資料,得到回復(fù)如下:
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 指針和指向函數(shù)的指針支持加法和減法操作。這是通過(guò)將 void 或函數(shù)的大小視為1來(lái)實(shí)現(xiàn)的。
因此,sizeof 操作符也可以用于 void 和函數(shù)類(lèi)型,并返回 1。選項(xiàng) -Wpointer-arith 會(huì)在使用這些擴(kuò)展時(shí)發(fā)出警告
——EOF——日常分享C/C++、計(jì)算機(jī)學(xué)習(xí)經(jīng)驗(yàn)、工作體會(huì),歡迎點(diǎn)擊此處查看我以前的學(xué)習(xí)筆記&經(jīng)驗(yàn)&分享的資源。
我組建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起進(jìn)群交流。

歡迎你添加我的微信,我拉你進(jìn)技術(shù)交流群。此外,我也會(huì)經(jīng)常在微信上分享一些計(jì)算機(jī)學(xué)習(xí)經(jīng)驗(yàn)以及工作體驗(yàn),還有一些內(nèi)推機(jī)會(huì)。


加個(gè)微信,打開(kāi)另一扇窗
經(jīng)常遇到有讀者后臺(tái)私信想要一些編程學(xué)習(xí)資源,這里分享 1T 的編程電子書(shū)、C/C++開(kāi)發(fā)手冊(cè)、Github上182K+的架構(gòu)路線圖、LeetCode算法刷題筆記等精品學(xué)習(xí)資料,點(diǎn)擊下方公眾號(hào)會(huì)回復(fù)"編程"即可免費(fèi)領(lǐng)取~
感謝你的分享,點(diǎn)贊,在看三  

發(fā)表回復(fù)

本版積分規(guī)則


聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表