Это в основном продолжение этого вопроса. Пока это выглядит так, если у меня есть такая функция:
void SecureZeroMemory( void* ptr, size_t cnt )
{
volatile char *vptr = (volatile char *)ptr;
while (cnt) {
*vptr = 0;
vptr++;
cnt--;
}
}
и назовите его следующим образом:
{
char buffer[size];
SecureZeroMemory( buffer, size );
}
так как buffer
не объявляется volatile, не имеет значения, что используется указатель на volatile - сами данные не являются изменчивыми, поэтому запись в переменную не является наблюдаемым поведением (1.9/6) и компилятором разрешено оптимизировать их.
Однако недавно я столкнулся с утверждением, что это имеет значение только для указателя указателя. В частности, С++ 03 5.3.1/1 описывает косвенность (*) следующим образом:
Унарный * оператор выполняет косвенное обращение [...] Если тип выражения является "указателем на T", то тип результата будет "T."
Таким образом, утверждение состоит в том, что из-за использования косвенности на volatile char*
мы получаем volatile char
, и записи на них составляют наблюдаемое поведение, и уже не имеет значения, как объявляются фактические данные.
Является ли описание косвенности С++ 03 5.3.1/1 действительно гарантией того, что перезапись памяти с помощью указателя volatile T*
, как в примере выше, является наблюдаемым поведением и запрещена для оптимизации?