Я экспериментирую с новым ключевым словом _Generic
и наткнулся на специальный случай, касающийся нескольких оценок. См. Следующее:
#include <stdio.h>
#define write_char(c) _Generic(c, char: putchar, const char: putchar)(c)
int main(void)
{
const char *s = "foo";
write_char(*s++);
write_char(*s++);
write_char(*s++);
putchar('\n');
}
Это компилирует штраф и дает ожидаемый результат с помощью GCC:
$ gcc -std=c11 -Wall plusplus.c -o plusplus
$ ./plusplus
foo
С другой стороны, Clang выводит большое предупреждение о гудении:
$ clang -std=c11 plusplus.c -o plusplus
plusplus.c:9:18: warning: multiple unsequenced modifications to 's'
[-Wunsequenced]
write_char(*s++);
^~
plusplus.c:3:32: note: expanded from macro 'write_char'
#define write_char(c) _Generic(c, char: putchar, const char: putchar)(c)
...
Однако результат будет таким, как ожидалось:
$ ./plusplus
foo
Я проверил проект стандарта, в котором говорится (на стр. 97 PDF):
Контролирующее выражение общего выбора не оценивается.
Это, по-видимому, точно решает проблему побочных эффектов в макросах (например, MIN
и MAX
).
Теперь, могу ли я безопасно игнорировать предупреждение Клана, или я ошибаюсь?