Обеспечивает ли доступ к объявленному энергонезависимому объекту через энергозависимую ссылку / указатель энергозависимые правила при указанных доступах?

Это будет длинный вопрос, так как для контекстуализации и предоставления как можно большего количества информации я должен извлекать различные ссылки и цитаты - что часто является единственным способом, как только мы входим в 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 объектдолжен генерировать код на основеклассификатор указателянезависимо от того, что из упомянутого объекта ...

Независимое от платформы решение «secure-memset»:
void *secure_memset(void *v, int c , size_t n) {
    volatile unsigned char *p = v;
    while (n--) *p++ = c;
    return v;
}

Такой подход предотвратит очистку памяти от оптимизации ион должен работать на любой стандартной платформе.

... и что компиляторы этого не делают

Там было недавнее уведомление о том, чтонекоторые компиляторы нарушают стандарт, не всегда соблюдаяvolatile Классификатор.


Кто прав?

Это было утомительно. Здесь, безусловно, есть много возможностей для интерпретации, в зависимости от того, какие документы вы прочитали, а какие нет, и от того, как вы решили интерпретировать много слов, которые недостаточно конкретны. Кажется очевидным, что что-то не так: либо:

Обоснование и N1381 неверно или случайно сформулированы, илиони были специально признаны недействительными задним числом ... илиСтандарт неверно или случайно сформулирован.

Я надеюсь, что мы сможем добиться большего успеха, чем все двусмысленности и спекуляции, которые, кажется, окружали это в прошлом, - и получить более убедительное заявление для записи. С этой целью любые дополнительные источники и мысли экспертов будут очень приветствоваться.

Ответы на вопрос(4)

Ваш ответ на вопрос