2016-06-10 2 views
1

я использовал const_cast модифицировать элементы внутри initializer_list, как показано ниже:C++ 11 модифицирующие элементы в файле initializer_list с использованием указателя, вызванного SIGSEGV, почему?

#include <initializer_list> 
int main() 
{ 
    auto a1={1,2,3}; 
    auto a2=a1;//copy or reference? 
    for(auto& e:a1) 
    { 
     int*p=const_cast<int*>(&e); 
     ++(*p); 
    } 
    for(auto& e:a2) 
     cout<<e; 
    return 0; 
} 

К сожалению, при выполнении ++ (* р) это г ++ 4.9.2 составлена ​​программа бросает SIGSEGV. Проблема не возникает в VC.

Почему у меня в программе какие-то небезопасные операции? Пожалуйста, помогите, спасибо.

+1

'auto a2 = a1;' никогда не будет ссылкой, только копией. Если вам нужна ссылка, вам нужно быть явным, как в 'auto & a2 = a1;' –

+3

. Вы выполнили 'const_cast', затем мутацию на кастинге, и вы хотите узнать, есть ли у вашей программы какие-либо небезопасные операции? –

ответ

3

В качестве I mentioned на ваш предыдущий вопрос базовый массив для initializer_list<T> составлен на const объектах. Изменение объявленных объектов const is неопределенное поведение. Из [dcl.type.cv]:

За исключением, что любой член класса объявлен изменяемый (7.1.1) может быть изменен, любая попытка изменить объект Const течение его срока службы (3.8) приводит к неопределенному поведению.

Одним из возможных экземпляров неопределенного поведения является SIGSEV, что вы видите из gcc. Другой возможный экземпляр - это код, который вы видите в VC. Только не делай этого.

5

Неопределенное поведение для изменения первоначально заявленных данных const, а содержимое списка инициализаторов всегда равно const.

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

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

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

Ваш жесткий диск может быть отформатирован, компьютер может взорваться, он отправит вашу историю веб-поиска родителям: компилятор может сделать код в любом случае по любой причине или без причины.

Не выполняйте неопределенное поведение.