Доступ к изменчивым локальным переменным не доступен извне функции, наблюдаемой в C ++? - PullRequest
6 голосов
/ 26 сентября 2011

В C ++ 03 Стандартное наблюдаемое поведение (1.9 / 6) включает чтение и запись изменчивых данных. Теперь у меня есть этот код:

int main()
{
    const volatile int value = 0;
    if( value ) {
    }
    return 0;
}

, который формально инициализирует переменную и затем читает ее. Visual C ++ 10 генерирует машинный код, который освобождает место в стеке, помещая туда меч, затем записывает ноль в это место в стеке и затем считывает это место.

Для меня это не имеет смысла - никакой другой код или оборудование не может знать, где находится локальная переменная (поскольку она находится в автоматическом хранилище), и поэтому не стоит ожидать, что переменная могла быть прочитана / записана любой другой стороной и поэтому это может быть устранено в этом случае.

Разрешено ли исключение этой переменной доступа? Доступ к изменчивому локальному адресу, адрес которого неизвестен какой-либо другой наблюдаемой стороне?

Ответы [ 6 ]

8 голосов
/ 26 сентября 2011

Весь стек потока может быть расположен на защищенной странице памяти с помощью обработчика, который регистрирует все операции чтения и записи (и, конечно, позволяет их завершать).

Однако я не думаю, что MSVCдействительно волнует, может ли быть обнаружен доступ к памяти.Он понимает volatile, что означает, среди прочего, «не пытайтесь применять оптимизацию к этому объекту».Так что нет.Это не имеет смысла, потому что MSVC не заинтересован в ускорении такого рода использования volatile.

Поскольку это зависит от реализации, можно ли наблюдать наблюдаемое поведение и насколько реально можно наблюдать, я думаю, что выВы правы, что реализация может «обмануть», если знает из-за деталей оборудования, что доступ не может быть обнаружен.Наблюдаемое поведение, которое не имеет физически обнаруживаемого эффекта, может быть пропущено: независимо от того, что говорится в стандарте, средства обнаружения несоответствующего поведения ограничены физически возможным.

Если реализация не соответствует стандартув лесу и никто не замечает, издает ли он звук?Вроде вещи.

3 голосов
/ 26 сентября 2011

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

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

2 голосов
/ 26 сентября 2011

никакой другой код или оборудование не может знать

Вы можете посмотреть сборку (вы только что сделали!), Выяснить адрес переменной и сопоставить ее с некоторым оборудованиемна время разговора.volatile означает, что реализация также обязана учитывать такие вещи.

1 голос
/ 26 сентября 2011

Для меня это не имеет смысла - никакой другой код или оборудование не может знать, где находится локальная переменная (поскольку она находится в автоматическом хранилище)

Правда?Поэтому, если я напишу эмулятор x86 и запусту на нем ваш код, то этот эмулятор не будет знать об этой локальной переменной?

Реализация может никогда на самом деле знать наверняка, что поведение ненаблюдаемо.

1 голос
/ 26 сентября 2011

Volatile также применяется к вашему собственному коду.

volatile int x;
spawn_thread(&x);
x = 0;
while (x == 0){};

Это будет бесконечный цикл, если x не является энергозависимым.

Что касается констант.Я не уверен, может ли компилятор использовать это, чтобы решить.

0 голосов
/ 09 января 2017

Мой ответ немного опоздал.В любом случае, это утверждение

Для меня это не имеет смысла - никакой другой код или оборудование не может знать, где находится локальная переменная (поскольку она находится в автоматическом хранилище)

неправильно.Разница между изменчивым или нет на самом деле очень заметна в VC ++ 2010.Например, в сборке выпуска нельзя добавить точку останова к объявлению локальной переменной, которое было устранено оптимизацией.Следовательно, если вам нужно установить точку останова для объявления переменной или даже просто посмотреть ее значение в отладчике, мы должны использовать сборку отладки.Чтобы отладить определенную локальную переменную в сборке выпуска, мы могли бы использовать ключевое слово volatile:

int _tmain(int argc, _TCHAR* argv[])
{
    int a; 
    //int volatile a;
    a=1; //break point here is not possible in Release build, unless volatile used

    printf("%d\n",a);
    return 0;
}
...