2016-02-26 53 views
3

最近我回答了一些question問如何實現一個結構成員的複雜const正確性。這樣做我使用通用表達式並遇到奇怪的行爲。下面是示例代碼:爲什麼這個通用表達式會被竊聽?

struct A 
{ 
    union { 
     char *m_ptrChar; 

     const char *m_cptrChar; 
    } ; 
}; 

#define ptrChar_m(a) _Generic(a, struct A *: a->m_ptrChar,  \ 
           const struct A *: a->m_cptrChar, \ 
           struct A: a.m_ptrChar,  \ 
           const struct A: a.m_cptrChar) 

void f(const struct A *ptrA) 
{ 
    ptrChar_m(ptrA) = 'A'; // NOT DESIRED!! 
} 

在GCC和鏘通用表達選擇時的a類型必須是struct A不使任何意義的情況。當我評論最後兩個案例,雖然它工作正常。這是爲什麼 - 它是否有一些錯誤?

上鐺確切的錯誤信息是:

test.c:17:5: error: member reference type 'const struct A *' is a pointer; did you mean to use '->'? 
    ptrChar_m(ptrA) = 'A'; // NOT DESIRED!! 
    ^
test.c:12:45: note: expanded from macro 'ptrChar_m' 
           struct A: a.m_ptrCHar,  \ 
              ^
test.c:17:5: error: member reference type 'const struct A *' is a pointer; did you mean to use '->'? 
    ptrChar_m(ptrA) = 'A'; // NOT DESIRED!! 
    ^
test.c:13:51: note: expanded from macro 'ptrChar_m' 
           const struct A: a.m_cptrChar) 
               ^
test.c:17:21: error: cannot assign to variable 'ptrA' with const-qualified type 'const struct A *' 
    ptrChar_m(ptrA) = 'A'; // NOT DESIRED!! 
        ^
test.c:15:24: note: variable 'ptrA' declared const here 
void f(const struct A *ptrA) 
        ^
test.c:23:18: error: invalid application of 'sizeof' to a function type [-Werror,-Wpointer-arith] 
    return sizeof(main); 
4 errors generated. 
+1

這是一個很好的問題,但包括編譯器輸出作爲截圖並不是那麼好。難道你不能將文本複製粘貼到問題中嗎? – unwind

+0

[THIS](http://stackoverflow.com/a/24746034/3436922)可能會回答你的問題 – LPs

回答

1

雖然非匹配選擇未被評估,編譯器仍然編譯代碼。因此,不允許在指向結構的指針上使用.運算符。

如果您的輸入表達式始終是一個變量,您可以採用表示結構實例的變量的地址。

#define AptrChar_m(a) _Generic(a, struct A *: a->m_ptrChar, \ 
            const struct A *: a->m_cptrChar) 
#define ptrChar_m(a) AptrChar_m(_Generic(a, struct A *: a, \ 
              const struct A *: a, \ 
              struct A: &a,  \ 
              const struct A: &a)) 
相關問題