Заявление:
volatile unsigned char * volatile p = (volatile unsigned char * volatile)v;
Генерирует предупреждение C4197 в MSVC v14.1:
Предупреждение C4197: "volatile unsigned char * volatile": волатильность верхнего уровня в листинге игнорируется
В стандарте 2011 C (раздел [N1570] 6.7.3 4.) говорится: "Свойства, связанные с квалифицированными типами, имеют смысл только для выражений, которые являются значениями l", таким образом, волатильность верхнего уровня в этом приведении игнорируется и генерирует это предупреждение.
Автор этого кода заявляет, что он не нарушает стандарт C и необходим для предотвращения некоторых оптимизаций GCC. Он иллюстрирует проблему с кодом по адресу: https://godbolt.org/g/xP4eGz
#include <stddef.h>
static void memset_s(void * v, size_t n) {
volatile unsigned char * p = (volatile unsigned char *)v;
for(size_t i = 0; i < n; ++i) {
p[i] = 0;
}
}
void f1() {
unsigned char x[4];
memset_s(x, sizeof x);
}
static void memset_s_volatile_pnt(void * v, size_t n) {
volatile unsigned char * volatile p = (volatile unsigned char * volatile)v;
for(size_t i = 0; i < n; ++i) {
p[i] = 0;
}
}
void f1_volatile_pnt() {
unsigned char x[4];
memset_s_volatile_pnt(x, sizeof x);
}
... где он показывает, что функция f1() ничего не компилирует (просто инструкция ret), но f1_volatile_pnt() компилируется в инструкции, которые выполняют задание.
ВОПРОС: Есть ли способ правильно написать этот код, чтобы он был правильно скомпилирован GCC и в соответствии со стандартом 2011 C (раздел [N1570] 6.7.3 4.), поэтому он не генерирует предупреждение с MSVC и ICC?... без #ifdef...
В контексте этой проблемы см.: https://github.com/jedisct1/libsodium/issues/687