моя программа пропускает оператор возврата - PullRequest
4 голосов
/ 11 июля 2010

Моя программа имеет эту функцию:

    vector<itemPtr> Level::getItemsAt(const Point& pt)
    {
        vector<itemPtr> vect(items.size());
        // copy all items at pt's position to vect
        remove_copy_if(items.begin(), items.end(), vect.begin(),
                       boost::bind(matchesPosition<itemPtr>, _1, pt));

        // update LevelMap and return
        map.setHasItem(pt, false);
        return vect;
    }

Это прекрасно компилируется (я использую g ++, моя версия gcc 4: 4.4.1-1ubuntu2), но когда я запускаю программу, она пропускает сразу оператор return.

Я прошел через GDB, установив точку останова на предыдущей строке, и получил это:

Breakpoint 1, yarl::level::Level::getItemsAt (this=0x80d4d58, pt=...)
at src/Level.cpp:519
519                 map.setHasItem(pt, false);
(gdb) next
521             }
(gdb) 

Я несколько раз пытался перекомпилировать с нуля, предварительно удалив исполняемый файл и все объектные файлы, и он все еще делает это.

Странно, если я закомментирую оператор return и попытаюсь скомпилировать, он выдаст только warning: no return statement in function returning non-void. Я бы подумал, что не предоставление оператора return в функции, которая возвращает что-то, было бы ошибкой компилятора, но я думаю, что нет.

Я понимаю, что это не так много, но у кого-нибудь есть идея, почему это происходит? Что проверить? На данный момент я даже не знаю, с чего начать.

РЕДАКТИРОВАТЬ: для уточнения, я компилирую с -O0.

Согласно tjm, моя версия gcc по-прежнему будет использовать RVO даже с флагом компилятора -O0, так что в конце концов это была проблема. Спасибо за вашу помощь, ребята.

Ответы [ 3 ]

6 голосов
/ 11 июля 2010

Исходный код C ++ не должен соответствовать результирующему объектному коду один-к-одному, пока сохраняется поведение.Здесь происходит то, что компилятор реорганизует код и, вероятно, вызывает Оптимизация возвращаемого значения .

Редактировать:

Добавьте это в параметры GCC: -fdump-tree-nrv, чтобы увидетьNRVO-приложения от компилятора (вы получите файл с расширением .nrv).Это работает только с уровнем оптимизации, превышающим -O0.

Без оптимизации замена оператора return на конструктор копирования или вызов оператора присваивания копирования по-прежнему является внешним преобразованием C ++, которое не обрабатывается изящноgdb.

1 голос
/ 11 июля 2010

Я могу вспомнить пару причин, по которым оператор return может быть пропущен - может ли это быть какой-то из них?

  • Исключение выдается в строке 519. Это звучит очень маловероятно, если в строке 521. ударил.
  • Компилятор оптимизировал строку оператора return - вы отлаживаете правильную отладочную сборку (оптимизация не включена)?

Хорошо ли работает функция - получает ли вызываемый абонент результат и продолжает веселиться?

0 голосов
/ 11 июля 2010

Правильно ли выделены и инициализированы объекты map и pt?

Если из строки 519 выдается исключение, метод обычно не возвращается. В этом случае вы можете ожидать, что следующая «выполненная» строка будет строкой 521, когда стек раскручивается.

Я видел довольно много этого в Visual C ++, когда код делает что-то, что приводит к "неопределенному поведению". У меня недостаточно опыта работы с g ++, чтобы понять, является ли наблюдаемое поведение таким же.

...