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

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

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

sizeof(void)之謎

[復(fù)制鏈接]

445

主題

445

帖子

3456

積分

四級會員

Rank: 4

積分
3456
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-10-16 09:02:00 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
最近有小伙伴說沒有收到當(dāng)天的文章推送,這是因為微信更改了推送機(jī)制,導(dǎo)致沒有星標(biāo)公眾號的小伙伴刷不到當(dāng)天推送的文章,無法接收到一些比較實用的知識和資訊。所以建議大家加個星標(biāo)??,以后就能第一時間收到推送了。


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

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


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

回復(fù)

使用道具 舉報

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

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則


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