簡體   English   中英

Visual Studio C ++編譯器中的錯誤?

[英]Bug in Visual Studio C++ compiler?

此代碼在MS Visual Studio中表現得很奇怪:

char *s = "hello";
s[0] = 'a';
printf(s); 

在啟用優化的發布版本中,它忽略s [0] ='a'並打印“hello”。 如果沒有優化或在調試版本中,它會因訪問沖突而崩潰。
這種行為是符合c ++標准還是沒有? 在我看來,編譯器應該只允許對字符串文字的常量引用,即

const char *s = "hello";

編輯 :我知道為什么它這樣工作,我不明白為什么我被允許非const引用只讀內存。

不,這不是編譯器中的錯誤。 當你寫:

char* s = "hello";

字符串常量"hello"將放在只讀部分中,如果您嘗試修改它,則應生成異常。 (OS異常,而不是C ++異常)。

要使其可寫,您必須使用數組:

char s[] = { 'h', 'e', 'l', 'l', 'o', 0 };

或者,如果你真的需要一個指針,讓它指向一個數組:

char _s[] = { 'h', 'e', 'l', 'l', 'o', 0 };
char* s = _s;

我可以看到你的觀點,即只允許使用字符串文字初始化const指針,但我認為這會破壞很多現有代碼。

首先允許此代碼的原因(而不是要求聲明為char const*類型)是對舊C代碼的向后兼容性。

但是,嚴格模式下的大多數現代編譯器都會對上面的代碼發出警告

我認為允許C ++編譯器按照標准在只讀存儲器頁面中分配字符串文字。

這不起作用,因為* s指向字符串常量的內存地址,您不允許更改。

我實際上有點驚訝你在使用優化編譯時不會遇到訪問沖突。

char *s = "foo";

是一個棘手的小馬。 它並沒有告訴你這實際上是一個只讀字符串。 就是這樣,因為,你可以讓你的同事寫下另一個字符串,如:

char *t = "foo";

現在,編譯器在其最有用的情況下只保留一個副本,而更改一個副本意味着很多工作只會讓你和你的朋友感到高興。 所以,它並沒有嘗試這樣做。 這是你應該在標准中找到的東西。 猜猜你正在做什么調用UB。

也就是說,如果你按照自己的方式行事,它將打破標准委員會中的窮人無法負擔的許多遺留代碼。 那么,你就是。

記住const我們犯了無憂無慮的用法並非一天出生。 Bjarne做了很多自我反省,很多其他人也做了很多的反省。 事實上,他有一個關於只讀和只寫變量的優秀想法......但是我會把這個故事保存到另一天。

最后,還有我們的好朋友C,我們需要照顧他們。 所以......

正如其他人所說,你無法修改字符串文字。 我也想知道為什么你的代碼中沒有編譯器警告。 編譯器可以肯定地發現你正在嘗試寫入只讀內存。

暫無
暫無

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

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