簡體   English   中英

可變函數中的std :: nullptr_t參數

[英]std::nullptr_t arguments in variadic functions

因此,當沒有參數(via ... )傳遞時,顯然std::nullptr_t參數被轉換為void *類型的空指針(N3337的第5.2.2 / 7節)。 這意味着要正確傳遞null char *指針,例如,仍然需要強制轉換:

some_variadic_function(“a”,“b”,“c”,(const char *)std :: nullptr);

因為無法保證null void *與null char *具有相同的位模式。 正確?

這也意味着在這種情況下std::nullptr超過0沒有任何優勢,除非為了清楚起見。

你問:

因為無法保證null void *與null char *具有相同的位模式。 正確?

嗯,實際上,這種保證確實存在,Deduplicator的答案已經顯示了標准要求的地方。 但這與你的問題無關。

void *傳遞給可變參數函數,並使用va_arg作為char *訪問它,特別允許作為特殊異常。

C ++ 11:

18.10其他運行時支持[support.runtime]

1標題<csetjmp> (非本地跳轉), <csignal> (信號處理), <cstdalign> (對齊), <cstdarg> (變量參數), <cstdbool>__bool_true_false_are_defined )。 (運行時環境getenv()system() )和<ctime> (系統時鍾clock()time() )提供了與C代碼的進一步兼容性。

2這些頭文件的內容與標准C庫頭<setjmp.h><signal.h><stdalign.h><stdarg.h><stdbool.h><stdlib.h><time.h>分別進行以下更改:

[......沒有關於va_arg ]

C99:

7.15.1.1 va_arg

[...]如果沒有實際的下一個參數,或者type與實際的下一個參數的類型不兼容(根據默認參數提升而提升),則行為是未定義的,除了以下情況:

- 一種類型是有符號整數類型,另一種類型是相應的無符號整數類型,並且該值可在兩種類型中表示;

- 一種類型是指向void的指針,另一種是指向字符類型的指針。

但是,這確實意味着在其他兩種類型T1T2具有相同的表示和對齊要求的情況下,如果T1被傳遞給可變參數函數,則行為是未定義的,並且它被檢索為T2

這樣的一個例子:使(void *) 0和訪問它作為char * ,是允許的,通過(void *) 0和訪問它作為unsigned char *也是允許的,但傳送(char *) 0和訪問它作為unsigned char *不允許的。 如果編譯器能夠內聯對可變參數函數的調用,並根據標准的嚴格要求進行優化,那么這種不匹配可能會嚴重破壞。

這也意味着在這種情況下std::nullptr超過0沒有任何優勢,除非為了清楚起見。

我絕對不會在沒有強制轉換的情況下使用nullptr ,即使在這種特殊情況下它也是有效的。 很難看出它是有效的。 如果無論如何都包含一個強制轉換, (char *) 0和空指針值一樣清晰。

你錯了。 少數保證之一是char*具有與相應void*相同的大小和表示。

3.9.2復合類型§4

指向cv-qualified(3.9.3)或cv-unqualified void的指針可用於指向未知類型的對象。 這樣的指針應該能夠保存任何對象指針。 cv void*類型的對象應具有與cv char*相同的表示和對齊要求。

編輯:看起來這個hvd的答案更好,顯示了一些特定於問題的可變函數部分的陷阱。

暫無
暫無

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

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