Действительно ли безопасно Выбросить энергозависимый?

Большую часть времени я делаю этот путь.

class a {
public:
    ~ a() {
        i = 100;          // OK
        delete (int *)j;  // Compiler happy. But, is it safe?
                          // The following code will lead compilation error : delete j;
    }

private:
    volatile int i;
    volatile int *j;
};

int main() {
    a aa;

}

Однако я видел статью здесь:

https://www.securecoding.cert.org/confluence/display/seccode/EXP32-C. + Do+not+access+a+volatile+object+through+a+non-volatile+reference

Выбрасывание энергозависимого предоставляет доступ к объекту через энергонезависимую ссылку. Это может привести к неопределенному и возможно непреднамеренному поведению программы.

Так, каково будет обходное решение для моего выше примера кода?

Вот сообщение об ошибке, которое я получаю, если я использую

удалите j

Обратите внимание, что, это производится от VC6 (Не спрашивайте, почему я использую VC6!)

c:\projects\a\a.cpp(5): ошибка C2664: 'удалите': не может преобразовать параметр 1 из 'энергозависимого интервала *' для 'освобождения *' Преобразование, теряет спецификаторы

8
задан Cheok Yan Cheng 22 March 2010 в 02:23
поделиться

4 ответа

Ничего. Если вы не обращаетесь к волатильной памяти, семантика volatile не затрагивается. Если вы обращаетесь к волатильной памяти через приведенный указатель на неволатильную, компилятор может оптимизировать ссылку. Если бы значение изменилось, у вас было бы неправильное значение. Для некоторого значения неправильного. ;-)

Удаление не обращается к энергозависимой памяти, оно просто освобождает ее. Вроде бы необычная вещь для работы с летучей памятью.

4
ответ дан 5 December 2019 в 18:58
поделиться

удаление переменной переменной подразумевает, что вы сериализовали доступ к ней, так что на самом деле она больше не является переменной . Правильный способ удаления volatile (когда вы знаете, что это безопасно) - const_cast.

Если указатель, а не int, является volatile, то вы действительно имели в виду int *volatile j. Более того, если все члены класса являются переменными, вы, вероятно, захотите определить весь объект сразу, a volatile aa;.

3
ответ дан 5 December 2019 в 18:58
поделиться

Это зависит от того, какое значение вы ожидаете от вашей переменной volatile. Сейчас j - это указатель на волатильное целое число; это то, что вы имеете в виду? Если да, то это безопасно, поскольку вам не нужно обращаться к изменчивому значению, только к его адресу, который не является изменчивым.

Если, однако, вы имели в виду, что вам нужен переменный указатель на целое число, то требуемый синтаксис - int* volatile j. В этом случае может быть проблематично сначала привести его к не volatile указателю, но я не думаю, что ваш компилятор будет жаловаться, если вы попытаетесь удалить его как есть. G++, например, этого не делает.

2
ответ дан 5 December 2019 в 18:58
поделиться

Это должно быть нормально, поскольку вы не обращаетесь к переменной после отбрасывания изменчивой . Однако я не знаю, почему вы все равно получите ошибку. Я сам пробовал этот код, и все, похоже, прошло нормально, что вы видели?

0
ответ дан 5 December 2019 в 18:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: