2016-02-26 7 views
3

Недавно я ответил question на вопрос о том, как реализовать комплексную корректность конструкции элемента структуры. Сделав это, я использовал общие выражения и столкнулся с странным поведением. Вот пример кода:Почему это обобщенное выражение вызывается?

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 и Clang общего выражения выберите случай, когда тип 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

[ЭТО] (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)) 

 Смежные вопросы

  • Нет связанных вопросов^_^