Большую часть времени я делаю этот путь.
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;
}
Однако я видел статью здесь:
Выбрасывание энергозависимого предоставляет доступ к объекту через энергонезависимую ссылку. Это может привести к неопределенному и возможно непреднамеренному поведению программы.
Так, каково будет обходное решение для моего выше примера кода?
Вот сообщение об ошибке, которое я получаю, если я использую
удалите j
Обратите внимание, что, это производится от VC6 (Не спрашивайте, почему я использую VC6!)
c:\projects\a\a.cpp(5): ошибка C2664: 'удалите': не может преобразовать параметр 1 из 'энергозависимого интервала *' для 'освобождения *' Преобразование, теряет спецификаторы
Ничего. Если вы не обращаетесь к волатильной памяти, семантика volatile не затрагивается. Если вы обращаетесь к волатильной памяти через приведенный указатель на неволатильную, компилятор может оптимизировать ссылку. Если бы значение изменилось, у вас было бы неправильное значение. Для некоторого значения неправильного. ;-)
Удаление не обращается к энергозависимой памяти, оно просто освобождает ее. Вроде бы необычная вещь для работы с летучей памятью.
удаление
переменной переменной
подразумевает, что вы сериализовали доступ к ней, так что на самом деле она больше не является переменной
. Правильный способ удаления volatile (когда вы знаете, что это безопасно) - const_cast
.
Если указатель, а не int
, является volatile, то вы действительно имели в виду int *volatile j
. Более того, если все члены класса являются переменными, вы, вероятно, захотите определить весь объект сразу, a volatile aa;
.
Это зависит от того, какое значение вы ожидаете от вашей переменной volatile. Сейчас j
- это указатель на волатильное целое число; это то, что вы имеете в виду? Если да, то это безопасно, поскольку вам не нужно обращаться к изменчивому значению, только к его адресу, который не является изменчивым.
Если, однако, вы имели в виду, что вам нужен переменный указатель на целое число, то требуемый синтаксис - int* volatile j
. В этом случае может быть проблематично сначала привести его к не volatile
указателю, но я не думаю, что ваш компилятор будет жаловаться, если вы попытаетесь удалить
его как есть. G++, например, этого не делает.
Это должно быть нормально, поскольку вы не обращаетесь к переменной после отбрасывания изменчивой
. Однако я не знаю, почему вы все равно получите ошибку. Я сам пробовал этот код, и все, похоже, прошло нормально, что вы видели?