2012-04-23 2 views
0

я потерял один час, чтобы найти эту проблему в моем коде:ссылка на временное и предупреждение

vector<string> & input_variables = parse_xml(xml_path)["variables"]; 

где parse_xml функция возвращает std::map<std::string, std::vector<std::string> >. Почему gcc не предупреждает меня (с -Wall)? Я пропускаю несколько флагов?

+0

[Вставить рекламу для 'valgrind' или подобных инструментов]. Нет, но на самом деле, он будет платить за себя в течение времени, сохраненного в обучении, чтобы использовать их;). – FatalError

+0

Просьба представить список полных флагов компиляции. В частности, ваши предупреждающие флаги – 111111

+0

Не следует ли продлевать срок службы временного периода, как указано в 12.2/5? – sharptooth

ответ

2

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

Технически, возвращаемое значение operator[] - это значение lvalue. К сожалению, он вот-вот будет уничтожен его владельцем, std::map.

+0

Вы уверены, что это было бы неверно в C++ 11? Проблема здесь в том, что возвращение 'parse_xml' является временным, но не постоянным объектом. –

+0

Я использую C++ 03 –

+0

@Let_Me_Be: В C++ 11 вы можете перегружать функции-члены, включая 'operator []' - на основе lvalue или rvalue. Это означает, что 'operator []' может возвращать временное-корректное предупреждение этого кода. 'const' не имеет к этому никакого отношения. – Puppy

0

Причина, почему он не предупреждает вас, потому что вы получаете недопустимую операцию через последовательность действительных шагов:

struct X 
{ 
    int c; 
    int & operator [] (int) { return c; } /* this is perfectly OK */ 
}; 

X f() 
{ 
    return X(); /* this is perfectly OK */ 
} 

int main() 
{ 
    int &x = f()[1]; /* can apply [] on temporary, therefore OK */ 
} 

Вы можете предотвратить это, явно отмечая результат f() в const ,

+0

'const' rvalues ​​- это плохо. Например, они не могут быть перемещены. – Puppy

+0

@DeadMG В ANSI C++? –

+0

ANSI? ANSI никогда не стандартизировала любую версию C++. Существует только ISO C++ - текущая версия которого была стандартизирована в прошлом году. – Puppy

1

GCC не предупреждает вас, потому что технически о нем ничего не известно.

parse_xml() возвращает std::map по стоимости, что является временным. Вызов operator[] возвращает ссылку. Компилятор не может знать локально что эта ссылка фактически частьstd::map временная. Для всех компиляторов известно, что operator[] может возвращать ссылку на глобальную или что-то в этом роде.

Членская переменная временного считается временной, которая связана со временем жизни внешнего временного. Но возвращаемое значение функции (например, operator[]) равно не так связано.

Смежные вопросы