[英]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 *
與nullchar *
具有相同的位模式。 正確?
嗯,實際上,這種保證確實存在,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的指針,另一種是指向字符類型的指針。
但是,這確實意味着在其他兩種類型T1
和T2
具有相同的表示和對齊要求的情況下,如果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*
類型的對象應具有與cvchar*
相同的表示和對齊要求。
編輯:看起來這個hvd的答案更好,顯示了一些特定於問題的可變函數部分的陷阱。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.