歡迎點擊上方藍色「泰曉科技」關注我們
作者:文平波
圖片來源自網絡
sizeof 是 C 中的一個關鍵字,用來計算類型或者表達式的大小。
今天在看書的時候,碰到一個問題,是說 sizeof 無法計算一個數組的大小,在編譯的時候,就出現錯誤。不解,自己嘗試著編寫了一個例子,果然出現這個錯誤:
錯誤:invalid application of 'sizeof' to incomplete type 'int[]'
例子如:
f1.h:
extern int array[];
extern int size;
int array2[10];
f1.c:
#include "f1.h"
int array[]={1,2,3};
int size = sizeof(array);
f2.c:
#include "f1.h"
#include "stdio.h"
#define TEST
int main(int argc, char *argv[])
{
printf("array: %d\n", size);
printf("array2: %d\n", sizeof(array2));
return 0;
}
可以看到,在 f2.c 中,第二個被注釋的 printf 是編譯不過去的,第三個正常。
WHY ?
因為 sizeof 是在編譯的時候來處理每個對象的大小,而編譯的時候是以一個文件 ( 編譯單元 ) 為單位進行編譯的。所以在處理一個編譯單元的時候,編譯器是無法從另外一個文件來獲得一個非完全聲明類型的大小的。這也是為什麼錯誤提示中有一個 incomplete type 的字眼了。
那麼,什麼是 incomplete type?
在 ISO-IEC 9899 的標準文檔的 6.2.5 中,是這樣來定義類型的:
The meaning of a value stored in an object or returned by a function is determined by the type of the expression used to access it. (An identifier declared to be an object is the simplest such expression; the type is specified in the declaration of the identifier.)
Types are partitioned into object types (types that describe objects) and function types (types that describe functions). At various points within a translation unit an object type may be incomplete (lacking sufficient information to determine the size of objects of that type) or complete (having sufficient information)
從上可以看出類型被分為:對象類型、函數類型。而在一個翻譯單元中,對象類型可能是完全的,或者非完全的。
也就是說非完全類型是對象類型的一個特殊類,而什麼時候,一個對象類型是不完全的呢?
標準文檔是這麼說的:缺乏足夠的信息來決定一個對象類型的大小
可能說這麼多,大家有點迷糊了,下面引用一下 IBM 在 XL C/C++ (V6.0) 的規範文檔中,把如下的類型歸類為非完全類型:
void 類型 eg. void *ptr;
沒有指明大小的數組 eg. extern int array[];
數組中的元素是非完全類型
沒有定義的結構體、union 和枚舉類型 eg. struct test;
沒有定義的類指針;
只聲明,無定義的類 eg. class test;
其實, incomplete type 一個經常的用處,那就是隱藏一些類型的細節,比如,在頭文件中聲明一個 struct test; ,然後其他程序如果要使用這個結構體,那就包含這個頭文件,但是它們無法知道這個結構體內部的細節,也就無法訪問結構體內部成員,當然,更加不能用 sizeof 。但是對於那些,只是做一個傳遞的外部函數,這些足夠了。
所以,以後用 sizeof 的時候,還是注意一下。
註:由於微信公眾號無法在正文中嵌入外部連結,所以這裡的文章為增強閱讀體驗移去了部分外部連結。如果您希望獲取正文中的外部連結請移步本文文末左下方點擊 「閱讀原文」。
上課啦!上課啦!
近日,泰曉科技與閱碼場強強聯合,首度推出程式設計師自我修養之 「360° 剖析 Linux ELF」在線視頻課程。如果您想進一步提升自己的實力,掌握更多有關 Linux 環境下程序編譯、連結、運行的底層奧秘,歡迎點擊 "課程介紹" 進入相關頁面了解更多訊息。
關注「泰曉科技」!點「在看」
~讚賞歸·原創作者·所有~