Хотя стандарт в первую очередь написан для руководства разработчиков, он записывается как описание того, что делает программу правильно сформированной, и каков ее эффект. Это потому, что базовое определение компилятора, соответствующего стандартам, - это то, что правильно работает для любой программы, соответствующей стандартам:
В строго соответствующей программе должны использоваться только те функции языка и библиотеки
указанный в этом международном стандарте .... Соответствующий
размещенная реализация принимает любую строго соответствующую программу.
Читайте отдельно, это чрезвычайно ограничение расширений для компилятора. Например, основываясь только на этом предложении, компилятор не должен определять любой своих собственных зарезервированных слов. В конце концов, любое данное слово, которое конкретный компилятор может хотеть зарезервировать , может, тем не менее, появиться в строго соответствующей программе, что заставит руку компилятора.
Стандарт продолжается, однако:
Соответствующая реализация может иметь расширения (включая дополнительные
библиотечные функции), при условии, что они не изменяют поведение каких-либо строго соответствующих
программа.
Это ключевой элемент. Расширения компилятора должны быть написаны таким образом, чтобы они влияли на несоответствующие программы (те, которые содержат неопределенное поведение, или которые вообще не должны компилироваться), позволяя им компилировать и делать забавные дополнительные вещи.
Таким образом, цель определения «зарезервированных идентификаторов», когда языку на самом деле не нужны эти идентификаторы для чего-либо, состоит в том, чтобы предоставить реализациям дополнительное пространство для маневра, предоставляя им некоторые вещи, которые делают программу несоответствующий. Причина, по которой компилятор может распознать, скажем, __declspec
как часть объявления, заключается в том, что помещение __declspec
в объявление в противном случае является незаконным, поэтому компилятору разрешено делать все, что он хочет!
Следовательно, важность слова «зарезервировано для любого использования» заключается в том, что он не оставляет никаких сомнений относительно способности компилятора обрабатывать такие идентификаторы как имеющие какое-либо значение, к которому они относятся. Совместимость в будущем - сравнительно отдаленная проблема.
Стандарт C ++ работает аналогичным образом, хотя в гамбите он немного более явный:
Соответствующая реализация может иметь расширения (включая дополнительные библиотечные функции), если они
не изменять поведение любой правильно сформированной программы. Реализации необходимы для диагностики программ, которые
использовать такие расширения, которые не соответствуют требованиям настоящего международного стандарта. Сделав это, однако,
они могут компилировать и выполнять такие программы.
Я подозреваю, что разница в формулировках сводится к стандарту C ++, просто яснее о том, как расширения должны работать. Тем не менее, ничто в стандарте C не мешает реализации делать то же самое. (И все мы в основном игнорируем требование, чтобы компилятор предупреждал вас каждый раз, когда вы используете __declspec
.)