Как к обходному решению предупреждение GCC, “адрес XXX никогда не будет ПУСТЫМ”?

Я работаю над программой C. Существует функция, которая берет два аргумента указателя, назовите ее cmp(). Я представляю здесь упрощенного заместителя для cmp() по иллюстративным причинам:

int cmp(struct foo *a, struct foo *b)
{
    return a->bar == b->bar;
}

Я хотел бы сделать макрос ПУСТОЙ проверки, как это:

#define SAFE_CMP(a,b) (((a) != NULL && (b) != NULL) ? cmp((a),(b)) : 0)

Я думаю, что это прекрасно подходит. Однако в при компиляции с обоими -Wall и переключатель компиляции, который рассматривает предупреждение как ошибку, следующий код, неприятен:

int baz(struct foo *a)
{
   struct foo b;
   /* ... */
   return SAFE_CMP(a, &b); 
}

так как gcc предупреждает, что "адрес b никогда не будет ПУСТЫМ".

Там каким-либо путем является к обходному решению эта ситуация? Наличие различного макроса помощника как SAFE_CMP_1(safe_arg,unsafe_arg) и SAFE_CMP_2(unsafe_arg,safe_arg) и т.д. последняя вещь, которую я хочу. Я хотел бы иметь один макрос помощника, применимый ко всем ситуациям.

6
задан caf 12 June 2018 в 03:03
поделиться

3 ответа

Кажется, это подавляет предупреждение для меня:

#define SAFE_CMP(a,b) (((void *)(a) != NULL && (void *)(b) != NULL) ? cmp((a),(b)) : 0)

... но лично я бы просто создал safe_cmp () как сама функция.

int safe_cmp(struct foo *a, struct foo *b) {
    return (a && b) ? (a->bar == b->bar) : 0;
}
12
ответ дан 8 December 2019 в 18:32
поделиться

«Я хотел бы иметь один вспомогательный макрос применимо ко всем ситуациям. "

Почему? Один размер не подходит всем. GCC делает вам одолжение, сообщая вам, что сравнение всегда будет иметь определенный результат. Адрес переменной стека будет никогда не будет NULL. Я бы просто выписал проверку в baz:

int baz(struct foo *a) {
   struct foo b;
   ...
   return a == NULL ? 0 : cmp(a, &b);
}

Вы также можете сделать это в cmp . Это зависит от того, как вы определяете предварительные и последующие условия.

Другая возможная проблема с вашим макросом (неприменима для baz) заключается в том, что a и b будут оцениваться несколько раз. Остерегайтесь:

SAFE_CMP(p++, p1++);
2
ответ дан 8 December 2019 в 18:32
поделиться

Параметр gcc -Wno-address , похоже, удаляет предупреждения.

0
ответ дан 8 December 2019 в 18:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: