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

PCB聯盟網

搜索
查看: 85|回復: 0
收起左側

sizeof(void)之謎

[復制鏈接]

454

主題

454

帖子

3643

積分

四級會員

Rank: 4

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


在 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開發(fā)的人,經常會見到形如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)好了,前面的一系列鋪墊,就是為了引入本節(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進行編譯:
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呢?
針對這個問題,繼續(xù)查資料,得到回復如下:
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 會在使用這些擴展時發(fā)出警告
——EOF——日常分享C/C++、計算機學習經驗、工作體會,歡迎點擊此處查看我以前的學習筆記&經驗&分享的資源。
我組建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起進群交流。

歡迎你添加我的微信,我拉你進技術交流群。此外,我也會經常在微信上分享一些計算機學習經驗以及工作體驗,還有一些內推機會。


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

回復

使用道具 舉報

發(fā)表回復

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

本版積分規(guī)則


聯系客服 關注微信 下載APP 返回頂部 返回列表