TU A содержит (только) определение a
. Таким образом, a
на самом деле неконстантный объект, и к нему можно получить доступ из функции A без проблем.
Я почти уверен, что TU B вызывает неопределенное поведение, так как его объявление a
не соответствует определению. Лучшая цитата, которую я нашел до сих пор, чтобы подтвердить, что это UB - 6.7.5 / 2:
Каждый декларатор объявляет один идентификатор и утверждает, что когда
операнд той же формы, что и декларатор, появляется в выражении,
он обозначает функцию или объект с объемом, продолжительностью хранения,
и тип, указанный в спецификации объявления.
[Редактировать: с тех пор вопросник нашел правильную ссылку в стандарте, см. Вопрос.]
Здесь объявление в B утверждает, что a
имеет тип volatile const int
. Фактически объект не имеет (квалифицированного) типа volatile const int
, он имеет (квалифицированный) тип int
. Нарушение семантики - UB.
На практике произойдет то, что TU A будет скомпилирован, как если бы a
не был константным. TU B будет скомпилирован, как если бы a
было volatile const int
, что означает, что он не будет кэшировать значение a
вообще. Таким образом, я ожидал бы, что это сработает, если компоновщик не заметит и не возражает против несовпадающих типов, потому что я не сразу вижу, как TU B может генерировать код, который идет не так. Тем не менее, мой недостаток воображения не совпадает с гарантированным поведением.
AFAIK, в стандарте нет ничего, что говорило бы, что volatile
объекты в области видимости файла не могут быть сохранены в совершенно другом банке памяти, чем другие объекты, которые предоставляют различные инструкции для их чтения. Реализация все равно должна быть способна читать нормальный объект, скажем, через указатель volatile
, поэтому предположим, например, что «нормальная» инструкция загрузки работает на «специальных» объектах, и она использует это при чтении через указатель к волатильно квалифицированному Но если (в качестве оптимизации) реализация выдает специальную инструкцию для специальных объектов, а специальная инструкция не не работает на обычных объектах, тогда происходит бум. И я думаю, что это ошибка программиста, хотя, признаюсь, я изобрел эту реализацию только 2 минуты назад, поэтому я не могу быть полностью уверен, что она соответствует.