簡體   English   中英

為什么/如何編譯?

[英]Why/how does this compile?

MS Visual Studio 2008中的C ++。警告級別4加上一系列額外警告也已啟用。 我希望這至少會發出警告,但更可能是編譯錯誤?

功能聲明如下:

int printfLikeFunction(
   const int               bufferLength,
   char * const            buffer,
   const char * const      format,
   ... );

代碼用法 - 有一個錯字:雖然傳入了outputBuffer的ARRAY_SIZE,但outputBuffer本身並不是 - 當然這不應該編譯:

printfLikeFunction( ARRAY_SIZE( outputBuffer ), "Format: %s, %s", arg1, arg2 );

顯然這是錯誤的,並且已經犯了錯誤。 但是編譯器應該抓住它! buffer參數應該是一個char指針,並且它正在傳遞一個字符串文字,這是一個const char-pointer。 這一定是個錯誤。 (arg1和arg2也是(可能是const)char指針,所以巧合的是聲明匹配,即使沒有outputBuffer在正確的位置)。

在運行時,此代碼在嘗試寫入字符串文字時崩潰。 毫不奇怪,我只是不明白如何允許編譯。

(雖然,順便說一下,這可能是為什么sprintf_s的緩沖區和大小參數與此函數的順序不同 - 它會使這些錯誤明確失敗)。

C ++對字符串文字有一個特殊的漏洞,可以與pre- const C風格的代碼兼容。 盡管字符串文字是const char數組,但它們可以轉換為指向非const char的指針。

釋義4.2 / 2 [conv.array]:'narrow'字符串文字可以轉換為非const char類型指針的右值。 僅當存在顯式目標類型(例如函數參數)時才考慮轉換,而不需要在需要進行右值轉換的一般左值時。

此轉換已棄用,但仍可用。 請注意,雖然轉換允許將文字轉換為指向非const char類型的指針,但仍會調用未定義的行為以嘗試通過此指針修改字符串文字中的任何字符。

我似乎記得編譯器有一個控制字符串文字處理方式的選項。 默認情況下,它們被視為char * ,以便不會破壞大量現有的非const安全代碼,但您可以將其更改為將它們視為const char * 這可能有助於觸發您正在尋找的錯誤。

(稍后)我目前沒有方便的Microsoft編譯器,但是在MSDN上查看引用我似乎無法找到這樣的選項。 我可能會想到GCC,它確實有這樣的選擇。

int printfLikeFunction(const int bufferLength,char * const buffer,const char * const format,...);

buffer參數指定為char * const,因此它只保護要修改的緩沖區地址,而不是緩沖區內容。

為了避免寫入緩沖區,需要將其聲明為const char * const格式。

編譯器允許寫入緩沖區,因為您將其聲明為char *。 const后綴修飾符僅阻止在函數中重新分配緩沖區值。

請參閱http://jriddell.org/const-in-cpp.html以查看const修飾符對變量的影響

C中的字符串文字是const char指針( char*const ),而不是const chars的const指針( const char* const )。

C ++最初遵循C用法,但隨后在某些時候修改了ANSI C ++標准(我不確定何時)使它們成為const char* const 傳統上,Microsoft產品往往傾向於重視與先前版本的兼容性而不是合規性 - 可能存在強制“新”行為的編譯器選項,但由於MSDN上的字符串文字的示例都是非const的,我懷疑是否存在。

暫無
暫無

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

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