簡體   English   中英

Memory 浪費? 如果 main() 應該只返回 0 或 1,為什么 main 聲明為 int 而不是 short int 甚至 char?

[英]Memory waste? If main() should only return 0 or 1, why is main declared with int and not short int or even char?

例如:

#include <stdio.h> 
int main (void)                         /* Why int and not short int? - Waste of Memory */ 
{
     printf("Hello World!");
     return 0; 
}

為什么main()是常規定義為int類型,它在 32 位上分配 memory 中的 4 個字節,如果它通常只返回 0 或 1,而其他類型如short int (2 bytes,32-bit) 甚至char ( 1 字節,32 位)會更節省 memory 嗎?

它正在浪費 memory 空間。

注意:這個問題不是給定線程的重復; 它的答案只對應於返回值本身,而不對應於其明確關注的數據類型。

問題是針對 C 和 C++。 如果這些之間的答案發生變化,請分享您的智慧,並提及特別關注哪種語言的上下文。

通常匯編器使用它們的寄存器來返回一個值(例如 Intel 處理器中的寄存器AX )。 int 類型對應於機器字,即不需要將例如char 類型對應的字節轉換為機器字。

事實上, main 可以返回任何 integer 值。

這是因為一台有半個世紀歷史的機器。

早在創建 C 的那一天, int是 PDP-11 上的機器字 - 16 位 - 擁有main返回是自然而有效的。

“機器字”是 B 語言中唯一的類型,它是 Ritchie 和 Thompson 較早開發的,並且是從 C 發展而來的。
當 C 添加類型時,不指定一個給你一個機器字 - 一個int
(當時節省空間非常重要,所以不需要拼出最常見的類型是一件非常好的事情。)

因此,由於 B 程序以

main()

程序員通常是語言保守的,C 做了同樣的事情並返回了一個int

我不認為這是浪費的原因有兩個:

1 4字節退出碼的實際使用

如果要返回一個准確描述錯誤的退出代碼,則需要超過 8 位。

例如,您可能希望對錯誤進行分組:第一個字節可以描述模糊的錯誤類型,第二個字節可以描述導致錯誤的 function,第三個字節可以提供有關錯誤原因的信息,第四個字節描述額外的調試信息。

2 填充

如果您傳遞單個short 或 char,它們仍將對齊以適合機器字,這通常是 4 字節/32 位,具體取決於架構。 這稱為填充,意味着您很可能仍需要 32 位 memory 來返回單個短字符或字符。

大多數 shell 的老式約定是使用int的最低有效 8 位,而不僅僅是 0 或 1。16 位越來越普遍,因為這是標准允許的int的最小大小。

浪費空間會有什么問題? 空間真的浪費了嗎? 您的計算機是否充滿了“東西”,以至於剩余的sizeof(int) * CHAR_BIT - 8會有所作為? 該架構能否利用這一點並將剩余的部分用於其他用途? 我非常懷疑。

所以我不會說 memory 完全被浪費了,因為你在程序完成時從操作系統中取回它。 也許奢侈 有點像用一個大酒杯喝一小杯酒?

第一: if it usually returns only 0 or 1單獨你的假設/陳述是錯誤的。

通常,如果沒有發生錯誤,則返回代碼應為0 ,否則它可以返回任何數字來表示不同的錯誤。 大多數(至少命令行程序)都這樣做。 許多程序還 output 負數。

However there are a few common used codes https://www.tldp.org/LDP/abs/html/exitcodes.html also here another SO member points to a unix header that contains some codes https://stackoverflow.com/a /24121322/2331592

因此,畢竟它不僅僅是CC++類型的東西,而且還有大多數操作系統如何工作並期望程序運行的歷史原因,因為語言必須支持這一點,所以至少C使用 an12F80B84D1 之類的語言這樣做int main(...)

第二:你的結論It is wasting memory space是錯誤的。

  1. 與較短的類型相比,使用int不會造成任何浪費。 無論如何,Memory 通常以字長處理(這意味着可能取決於您的架構)
  2. 使用子字類型涉及某些架構上的計算開銷(讀取:加載,字,屏蔽無關位;存儲:加載 memory,屏蔽變量位,或者使用新值,寫回字)
  3. 除非您使用它,否則不會浪費 memory。 如果你寫return 0; 此時從未使用過 memory。 如果您return myMemorySaving8bitVar; 您只使用了 1 個字節(最有可能在堆棧上(如果根本沒有優化))

答案是“因為它通常不會返回 0 或 1”。 我從軟件工程社區找到了這個帖子,它至少部分回答了你的問題。 以下是兩個亮點,首先來自已接受的答案:

integer 為報告錯誤提供了比一個字節更多的空間。 它可以被枚舉(返回 1 表示 XYZ,返回 2 表示 ABC,返回 3,表示 DEF 等)或用作標志( 0x0001表示失敗, 0x0002表示失敗, 0x0003表示失敗和失敗)。 將其限制為僅一個字節很容易用完標志(只有 8 個),因此決定可能是使用 integer。

Keith Thompson還提出了一個有趣的觀點:

例如,在Plan 9操作系統中使用的 C 的方言中, main通常聲明為void function,但是通過將字符串指針傳遞給exits() ZC1C425268E68A47,將退出狀態返回給調用環境。 空字符串表示成功,任何非空字符串表示某種失敗。 可以通過讓main返回一個char*結果來實現。

這是來自unix.com 論壇的另一個有趣的部分:

(以下一些可能是 x86 特定的。)

回到原來的問題:退出狀態存儲在哪里? kernel 內部。

當您調用 exit(n) 時,integer n 的最低有效 8 位被寫入 cpu 寄存器。 然后 kernel 系統調用實現會將其復制到與流程相關的數據結構中。

如果你的代碼沒有調用exit()怎么辦? 負責調用 main() 的 c 運行時庫將代表您調用 exit() (或其一些變體)。 main() 的返回值在寄存器中傳遞給 c 運行時,用作 exit() 調用的參數。

與最后一個報價相關,這是來自cppreference.com的另一個報價

5) 執行返回(或到達 main 結束時的隱式返回)等價於先正常離開 function(這會破壞具有自動存儲持續時間的對象),然后使用與參數相同的參數調用 std::exit的回報。 (std::exit 然后銷毀 static 對象並終止程序)

最后,我在這里找到了這個非常酷的示例(盡管帖子的作者說返回的結果是返回值模 512 是錯誤的)。 編譯並執行以下命令后:

int main() {
    return 42001;
}

符合 POSIX 的 my* 系統上, echo $? 返回 17。那是因為42001 % 256 == 17這表明實際使用了 8 位數據。 考慮到這一點,選擇int可確保有足夠的存儲空間可用於傳遞程序的退出狀態信息,因為根據此答案,符合 C++ 標准可確保int的大小(以位為單位)

不能小於8。這是因為它必須足夠大以容納“Unicode UTF-8編碼形式的八位代碼單元”。

編輯:

*正如Andrew Henle在評論中指出的那樣:

完全符合 POSIX 的系統使整個int返回值可用,而不僅僅是 8 位。 請參閱pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html :“如果si_code等於CLD_EXITED ,則si_status保存進程的退出值;否則,它等於導致進程更改 state. si_status中的退出值應等於完整退出值(即傳遞給_exit()_Exit()exit()的值,或從main()返回的值);不受限制到該值的最低有效八位。”

我認為這為使用int而不是較小大小的數據類型提供了更強有力的論據。

您正在工作或學習 C,所以我認為您關心效率是一個真正的好主意。 但是,這里似乎有幾件事需要澄清。

首先, int 數據類型並不是“32 位”的意思。 這個想法是 int 將是目標機器上最自然的二進制 integer 類型——通常是寄存器的大小。

其次,來自 main() 的返回值旨在適應不同操作系統上的各種實現。 POSIX 系統使用無符號的 8 位返回碼。 Windows 使用由 CMD shell 解釋為 2 的補碼符號的 32 位。 另一個操作系統可能會選擇其他東西。

最后,如果您擔心 memory “浪費”,那么在這種情況下,這是一個實現問題,甚至不是問題。 來自 main 的返回碼通常在機器寄存器中返回,而不是在 memory 中,因此不涉及成本或節省。 即使有,在運行一個重要程序時節省 2 個字節也不值得任何開發人員的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM