簡體   English   中英

為什么在給變量分配超出范圍的值時由編譯器決定要分配什么值

[英]why it is up to the compiler to decide what value to assign when assigning an out-of-range value to a variable

在C ++ Primer 4th Edition 2.1.1中,它說“當給有符號類型分配超出范圍的值時,由編譯器決定要分配的值”。

我聽不懂 我的意思是,如果您有類似“ char 5 = 299”的代碼,則編譯器將生成asm代碼,例如“ mov BYTE PTR _sc$[ebp], 43 “(VC)或” movb $43, -2(%ebp) “( gcc + mingw),由編譯器決定。

但是,如果我們分配用戶輸入給出的值怎么辦? 例如,通過命令行? 並且生成的asm代碼將為“ movb %al, -1(%ebp) ”(gcc + mingw)和“

mov cl, BYTE PTR _i$[ebp]
mov BYTE PTR _sc$[ebp], cl

“(VC),所以現在編譯器如何決定將要發生的事情?我認為現在由CPU決定。

你能給我一個清晰的解釋嗎?

是否由CPU決定由編譯器決定。 :)

C ++標准指定了程序的行為方式。 編譯器確保實現此行為。 如果您執行標准未指定的操作,則編譯器可以執行其喜歡的任何操作。 它可能會產生錯誤消息,向您的祖母發送電子郵件或破解您的銀行帳戶。 或者它仍然可以生成代碼,是的,然后由CPU決定下一步將發生什么。

但是重點是,CPU不負責確保您的程序按照C ++標准的規定運行。 編譯器是。 因此,由編譯器決定如何處理與標准的任何偏差(即使它經常選擇不做任何特別的事情,但這仍然是編譯器的決定)。

當然。 在這種情況下,“由編譯器決定”(Stanley Lippman的書)的意思是“它不是由標准強制執行的”。

編譯器沒有專門決定或不一定生成用於處理這種情況的代碼。 它可能取決於平台。

這將是未定義行為的示例。 C ++標准包含許多這樣的句子:“如果(某些條件),結果是不確定的行為”。

為什么存在未定義的行為? 不僅會使事情變得更復雜嗎? 是的,不幸的是,它確實使程序員變得更加復雜。 UB的原因是簡化了編譯器編寫器的工作-首先使編寫器更容易(或根本不可能!),或者通過確定確定性來使編譯器更容易實現優化假設。

基本上,編寫C ++程序時應遵循許多規則。 編譯器可以在編譯時很容易地檢測到某些違反這些規則的情況,對於這些語言,該語言要求編譯器發出錯誤消息。 例如語法錯誤。

但是也存在一些編譯器難以檢測或無法檢測到的違規情況。 這樣的一個例子是在調用delete后可以繼續使用的內存。 理論上講 ,實際上不可能編寫一個程序來檢測所有可能的此類違規。 因此,與其要求編譯器作者解決檢測這些違規問題所無法解決的問題,不如說,C ++標准聲明您的程序將遇到“未定義的行為”。 這意味着,你不能讓會怎么樣任何預測-事實上的標准的例子是,UB可能導致惡魔飛出你的鼻子

[編輯]實際上,正如litb指出的那樣,您的具體情況不是未定義行為的示例,而是實現定義的行為的示例,該示例更為文明。 :)此類別描述了C ++標准的作者認識到程序員可以合理預期某種一致行為並且對於編譯器編寫者來說很難實施的情況,但是要求這種行為將是繁重的或適得其反的在每個實現上都相同。 (例如, sizeof (int)是實現定義的-盡管就C ++標准而言,通常為4或8,但唯一的要求是>= sizeof (short) 。)對於要求標准的編譯器一致性,它必須記錄在標准中標記為“實現定義的行為”的每種情況下將發生的特定行為。

當然編譯器會生成asm代碼

您正在將C ++語言與在一個特定平台上的一種可能實現混淆。

我認為這是指這樣的情況:

char c = 3456234242424 ;

3456234242424大於簽名的char可以容納的大小,因此它將溢出。 然后應將其設置為char的最大正值還是最小的負值? 語言標准沒有強制要求它,因此,由編譯器決定要分配的值

對此的另一個常見描述是“依賴於實現”。 語言本身並不要求做什么,但必須做些事情。 因此,實現該語言的編譯器可以/必須決定。

對於大多數實現,將int分配給char ,編譯器會生成代碼,該代碼訪問int的低位字節,並將其存儲在char中。 在您的示例中,命令行輸入將存儲在大於char的變量中,例如int,然后將其分配給char,從而截斷字節。

CPU“永不”失敗,也沒有決定權,因為它們不可能處理超出范圍的值。 在asm代碼段中,根本沒有關於超出范圍的值的信息,一旦正確生成了指令,該信息就不會再出現(如果操作數不適合一個整數的大小,則匯編程序將不會進行匯編)。操作,例如mov al, 123456ABh會引發錯誤,並且不會生成任何代碼,因為沒有指令可以使32位值加載到8位寄存器中!)

問題完全取決於編譯器和標准規范。 在這種情況下,這意味着當您嘗試為無法容納該變量的變量分配一個數字時,該標准並沒有規定確切的行為。因此,編譯器實現“決定”了實際發生的情況。

暫無
暫無

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

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