Быстрый ответ: сбросьте флаг -O1 или восстановите компилятор до более ранней версии. Любой из них заставил предупреждение исчезнуть в моей системе. Я должен был собрать и использовать gcc4.4, чтобы получить предупреждение. (черт возьми, это огромная система)
Нет? Я думал, что нет.
Я действительно не понимаю, что C ++ делает со своими объектами, и как именно они освобождаются. Тем не менее, комментарий OP о том, что проблема не возникала, если вместо argc для размера вектора использовалось постоянное значение, дает мне возможность высунуть мою шею. Я рискну предположить, что C ++ использует указатель __first для освобождения только тогда, когда начальное распределение не является константой. На более высоком уровне оптимизации компилятор использует регистры больше, и существует конфликт между распределениями до и после setjmp ... Я не знаю, это не имеет смысла.
Общий смысл этого предупреждения: «Вы уверены, что знаете, что делаете?» Компилятор не знает, знаете ли вы, какое значение '__first' будет при выполнении longjmp, и получите ненулевой возврат из setjmp. Вопрос в том, является ли его значение после (ненулевого) возврата значением, которое было помещено в буфер сохранения, или значением, которое вы создали после сохранения. В этом случае это сбивает с толку, потому что вы не знали, что используете «__first», и потому что в такой простой программе нет (явного) изменения на «__first»
Компилятор не может анализировать логический поток в сложной программе, поэтому он, очевидно, даже не пытается выполнить какую-либо программу. Это допускает возможность того, что вы изменили значение. Так что это просто дружеский «хедз-ап». Компилятор второй угадывает вас, пытаясь быть полезным.
Если вы упрямы с выбором компилятора и оптимизацией, есть исправление программирования. Сохраните окружающую среду перед выделением вектора. Переместите setjmp вверх в начало программы. В зависимости от использования вектора и логики ошибок в реальной программе, это может потребовать других изменений.
редактировать 1/21 -------
мое оправдание (используется g ++ - mp-4.4 -Wextra -O1 main.cpp):
#include <setjmp.h>
#include <vector>
#include <iostream>
int main(int argc, char**) {
jmp_buf env;
int id = -1, idd = -2;
if ((id=setjmp(env)))
idd = 1;
else
idd = 0;
std::cout<<"Start with "<< id << " " << idd <<std::endl;
std::vector<int> foo(argc );
if(id != 4)
longjmp(env, id+1);
std::cout<<"End with "<< id << " " << idd <<std::endl;
}
Нет предупреждений; произведено:
Начать с 0 0
Начните с 1 1
Начните с 2 1
Начните с 3 1
Начните с 4 1
Конец с 4 1