Ответ 1
Я думаю, что ключом здесь является то, разрешено ли isalpha
быть макросом или нет. C11 7.1.4 вкратце упоминается
Любая функция, объявленная в заголовке, может быть дополнительно реализована как функционально подобный макрос, определенный в заголовке
хотя эта глава в основном связана с именами коллизий и многопоточными проблемами и т.д. С другой стороны, C11 7.4 говорит:
Заголовок объявляет несколько функций, полезных для классификации и отображения символов.
и C11 7.4.1.2:
int isalpha(int c);
Функция isalpha...
Мое isalpha
состоит в том, что isalpha
следует рассматривать как функцию. При реализации в качестве макроса должна быть обеспечена определенная проверка типа.
Учитывая, что это функция, это довольно ясно. Для всех функций правила вызова функции указаны в C11 6.5.2.2:
Если выражение, которое обозначает вызываемую функцию, имеет тип, который включает прототип, аргументы неявно преобразуются, как если бы по назначению, типам соответствующих параметров, считая тип каждого параметра безусловной версией объявленного тип.
Обратите внимание на часть "как по заданию". Это приводит нас к правилам простого назначения C11 6.5.16.1, ограничений. Код в вопросе за линиями будет эквивалентен выражению присваивания, такому как int c = (char[]){"X"};
где левый операнд является арифметическим типом, а правый операнд - указателем. Такой случай не может быть найден нигде в C11 6.5.16.1.
Поэтому код является нарушением ограничения 6.5.16.1.
Если компилятор lib хочет реализовать isalpha
в качестве макроса и, таким образом, теряет способность проверки типа каким-либо образом, не выполняя нормальное преобразование параметров функции во время назначения, тогда эта библиотека может быть очень несовместимой, если компилятор не может создать диагностическое сообщение.