簡體   English   中英

_Generic表達式的無效分支導致編譯器錯誤(C11)

[英]Dead branch of _Generic expression causing compiler error (C11)

我很想寫一個類型驗證宏,它只在類型不是int / short / long或pointer時才發出警告。

我遇到的麻煩是指針可以是任何類型的指針。

#define INT_OR_POINTER_AS_UINTPTR(v) _Generic((v), \
    signed long:  (uintptr_t)(v),            unsigned long:  (uintptr_t)(v), \
    signed int:   (uintptr_t)(v),            unsigned int:   (uintptr_t)(v), \
    signed short: (uintptr_t)(v),            unsigned short: (uintptr_t)(v), \
    default: (((void)(0 ? (*(v)) : 0),                       (uintptr_t)(v))))

第一個塊是允許int/short/long

default情況是允許任何指針。

(0 ? (*(v)) : 0)的意圖是,如果v不是指針,則導致編譯器錯誤,但否則不影響所生成的代碼(將0 ? ...改為)。

這樣,來自其他類型(例如floatbool意外隱式轉換將不會被忽略。

理想情況下,這將起作用。

int a = 4;
struct Foo *b = NULL;

uintptr_t test_a = INT_OR_POINTER_AS_UINTPTR(a);
uintptr_t test_b = INT_OR_POINTER_AS_UINTPTR(b);

理想情況下,這兩種用途都會失敗。

float a = 4;
struct Foo b = {0};

uintptr_t test_a = INT_OR_POINTER_AS_UINTPTR(a);
uintptr_t test_b = INT_OR_POINTER_AS_UINTPTR(b);

但是,即使以int/long/short作為參數,也會評估檢查指針的代碼並出錯: invalid type argument of unary '*' (have 'int')

不必顯式枚舉可能傳遞給此_Generic每種類型的指針,是否有一種方法可以捕獲所有類型的指針,而無需為其他(非指針)值評估表達式?

_Bool是“標准無符號整數類型”,請參見6.2.5,因此,如果要對此進行特殊處理,則需要單獨進行處理。

否則,您可以使用一個簡單的技巧。 整數和指針的性質是對稱差是整數。 因此,我們在只能接受整數的上下文中使用對稱差,例如數組下標:

#define INT_OR_POINTER_AS_UINTPTR(v) \
             ((sizeof "Allow only integer and pointer types"[(v)-(v)]), (uintptr_t)(v))

對於struct類型,該減法將失敗,並且浮點類型將產生一個浮點差,該差不能用於指針算術。

要拒絕_Bool ,可以使用_Generic

暫無
暫無

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

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