Обеспечивает ли доступ к объявленному энергонезависимому объекту через энергозависимую ссылку / указатель энергозависимые правила при указанных доступах?
Это будет длинный вопрос, так как для контекстуализации и предоставления как можно большего количества информации я должен извлекать различные ссылки и цитаты - что часто является единственным способом, как только мы входим в C / C ++ Standard Rabbit Hole. Если у вас есть лучшие цитаты или какие-либо другие улучшения этого поста, пожалуйста, дайте мне знать. Но, чтобы подвести итог заранее,Вы можете обвинить @zwol для меня это сообщение ;-) и цель состоит в том, чтобы найти истину из двух положений:
Выполните C и (путем импорта; см. Комментарии) Стандарты C ++ требуют, чтобы доступ осуществлялся черезvolatile *
или жеvolatile &
должен ссылаться на объект, первоначально объявленныйvolatile
чтобы иметьvolatile
семантика?Или жеполучает доступ кvolatile
квалифицированный объект черезvolatile
указатель / ссылка достаточны / должны заставить эти обращения вести себя так, как если бы объект был объявленvolatile
?И так или иначе, если (как кажется) формулировка несколько двусмысленна по сравнению с намерением -мы можем получить это ясно в самих стандартах?
Первая из этих взаимоисключающих интерпретаций чаще встречается, и это не совсем безосновательно. Тем не менее, я надеюсь показать, что есть существенное количество «разумных сомнений» в пользу 2-го, особенно когда мы вернемся к некоторым предыдущим отрывкам в «Обосновании» и «РГ».
volatile
Вчерашний популярный вопросЯвляется ли определение «изменчивым» таким изменчивым, или GCC имеет некоторые стандартные проблемы соответствия? возникла, предполагаяvolatile
ссылка дастvolatile
поведение на неvolatile
референт - но обнаружил, что это не так, или сделал в различной степени и непредсказуемым образом.
В принятом ответе изначально сделан вывод, что имеет значение только заявленный тип референта. Это и большинство комментариев, похоже, согласились с тем, что эквивалентные принципы действуют, как мы хорошо знаем дляconst
: поведение будет толькоvolatile
(или определяется вообще), если ссылка имеет тот жерезюме-квалификация в качестве упомянутого объекта:
Ключевое слово в этом отрывке - объект.volatile sig_atomic_t flag;
это изменчивый объект.*(volatile char *)foo
это простодоступ через изменчивую квалификацию lvalue и стандарт не требует, чтобы он имел какие-либо специальные эффекты, -zwol
Такое толкование, по-видимому, довольно широко распространено, как видно из ответов на этот похожий, но, надеюсь, не дублирующий вопрос:Требования к поведению указателя на volatile, указывающего на энергонезависимый объект Но даже там есть неопределенность: сразу после ответа «нет», затем «возможно»! В любом случае ... давайте проверим Стандарт, чтобы увидеть, на чем основаны «нет».
C11,N1548, §6.7.3: Понятно, что это UB для доступа к объектуопределяется с volatile
или жеconst
введите через указатель, который не разделяет указанный классификатор ...
6 Если сделана попытка изменить объект, определенный сconst
квалифицированный тип посредством использования lvalue сconst
-квалифицированный тип, поведение не определено. Если сделана попытка обратиться кобъект, определенный сvolatile
квалифицированный тип через использование lvalue сvolatile-
квалифицированный тип, поведение не определено. (133)
... Стандарт, кажется, не упоминает прямо противоположный сценарий, а именноvolatile
, Более того, при подведенииvolatile
и операции на нем, теперь он говорит об объекте, которыйимеет volatile
-квалифицированный тип:
7 объект, который имеетvolatile
квалифицированный тип могут быть изменены способами, неизвестными для реализации или иметь другие неизвестные побочные эффекты. Поэтому любое выражение, относящееся к такому объекту, должно оцениваться строго в соответствии с правилами абстрактной машины, как описано в 5.1.2.3. Кроме того, в каждой точке последовательности значение, сохраненное последним в объекте, должно соответствовать значению, предписанному абстрактной машиной, за исключением случаев, когда оно изменено неизвестными факторами, упомянутыми ранее. (134) Что представляет собой доступ к объекту, который имеетvolatile
тип определяется реализацией.
Должны ли мы предполагать, что «имеет» эквивалентно «был определен с»? или жеможет "имеет" ссылаетесь на комбинацию объектных и ссылочных классификаторов?
Комментатор суммировал проблему с такой формулировкой:
Отn1548 §6.7.3 the6 стандарт использует фразу «объект, определенный с типом с изменяемой спецификацией», чтобы отличить его от «lvalue с типом с квалифицированной спецификацией». К сожалению, этот «объект, определенный с различием» по сравнению с «lvalue», не переносится, и стандарт затем использует «объект, имеющий тип, определяемый volatile», и говорит, что «то, что составляет доступ к объекту, который имеет тип, определяемый volatile» определяется реализацией "(которая могла бы сказать" lvalue "или" объект, определенный с "для ясности). Ну что ж. -Дитрих Эпп
Пункт 4 того же раздела, кажется, цитируется реже, но вполне может иметь значение, как мы увидим в следующем разделе.
volatile
указатель / ссылка предназначена для присвоенияvolatile
семантика на ее разыменование?Вышеупомянутый ответ содержит комментарий, в котором автор цитирует более раннее заявление Комитета, в котором ставится под сомнение идея «ссылка должна соответствовать референту»:
Интересно, что там есть одно предложение [Обоснование C99 дляvolatile
] это означает, что комитетозначало за*(volatile T*)x
заставить этот доступ кx
быть обращенным как изменчивый; но фактическая формулировка стандарта не достигает этого. - Звол
Мы можем найти немного больше информации об этом бите Обоснования, из 2-го вышеупомянутого потока:Требования к поведению указателя на volatile, указывающего на энергонезависимый объект
С другой стороны,эта почта цитаты из 6.7.3 Обоснования международного стандарта - Языки программирования - C:
Преобразование значения в квалифицированный тип не имеет никакого эффекта; квалификация (скажем, изменчивая) может не повлиять на доступ, так как это произошло до рассмотрения дела.Если необходимо получить доступ к энергонезависимому объекту с помощью изменчивой семантики, метод заключается в приведении адреса объекта к соответствующему типу указателя на уточненный тип, а затем разыменовании этого указателя.
—philipxy
И изэтот поток байтовмы упоминаем C99 s6.7.3 p3 - a.k.a. C11's p4 - и этот анализ:
Данный абзац находится непосредственно перед разделом 6.7.3.1 в обосновании документа. Если вам также нужно привести цитату из самого стандартного документа, приведите6.7.3 р3:
Свойства, связанные с квалифицированными типами, имеют смысл только для выражений, которые являются lvalues.
Выражение(volatile WHATEVER) non_volatile_object_identifier
являетсяне lvalue, следовательно, термин «volatile» не имеет смысла.
И наоборот, выражение* (volatile WHATEVER *) & non_volatile_object_identifier
является lvalue (он может быть размещен слева от оператора присваивания), поэтому свойство квалификатора 'volatile' имеет в этом случае предполагаемое значение.
—Тим Рентш
Eстьочень конкретная демонстрация в поддержку этой идеи, с особым учетом 1-го связанного вопроса, вWG PaperN1381, Это введено в приложениеmemset_s()
делать то, что хотел этот ОП - гарантировать незаполненное заполнение памяти. При обсуждении возможных реализаций, кажется, поддерживается идея - без указания какого-либо требования - что использованиеvolatile
указатель, чтобы изменить не-volatile
объектдолжен генерировать код на основеклассификатор указателянезависимо от того, что из упомянутого объекта ...
void *secure_memset(void *v, int c , size_t n) {
volatile unsigned char *p = v;
while (n--) *p++ = c;
return v;
}
Такой подход предотвратит очистку памяти от оптимизации ион должен работать на любой стандартной платформе.
... и что компиляторы этого не делают
Там было недавнее уведомление о том, чтонекоторые компиляторы нарушают стандарт, не всегда соблюдаяvolatile
Классификатор.
Это было утомительно. Здесь, безусловно, есть много возможностей для интерпретации, в зависимости от того, какие документы вы прочитали, а какие нет, и от того, как вы решили интерпретировать много слов, которые недостаточно конкретны. Кажется очевидным, что что-то не так: либо:
Обоснование и N1381 неверно или случайно сформулированы, илиони были специально признаны недействительными задним числом ... илиСтандарт неверно или случайно сформулирован.Я надеюсь, что мы сможем добиться большего успеха, чем все двусмысленности и спекуляции, которые, кажется, окружали это в прошлом, - и получить более убедительное заявление для записи. С этой целью любые дополнительные источники и мысли экспертов будут очень приветствоваться.