2016-11-08 14 views
13

На недавней охоте за ошибками я обнаружил проблему с возвратом указателя на член временной переменной. Оскорбительный (упрощенный) код:Как предотвратить возврат указателя на временную переменную?

struct S { 
    S(int i) : i(i) {} 
    int i; 
    int* ptr() { return &i; } 
}; 

int* fun(int i) { return S(i).ptr(); } // temporary S dies but pointer lives on 

int main() { 
    int* p = fun(1); 
    return *p; // undefined 
} 

Как предотвратить это? GCC & Clang имеют -Waddress-of-temporary и -Wreturn-stack-address, но они, похоже, теряют след из-за ptr(), выступая в роли среднего человека за грязные дела. Они срабатывают только тогда, когда указатель берется непосредственно:

int* fun(int i) { return &S(i).i; } // rightly fails to compile 

Мой проект также включает в себя cppcheck в непрерывной интеграции, но он также не может забрать его (поднятый here).

Какой инструмент статического анализа может предотвратить этот класс ошибок?

EDIT: GCC делает это с версии 6.1.0 с -Wreturn-local-addr и (удивительно) -O2 включен.

+3

Если вы скомпилируете '-O2', gcc поймает эту ошибку: http://melpon.org/wandbox/permlink/KaXY4ktTM1vMNTiX – krzaq

+11

« Как предотвратить это? » существует только одно решение - прекратить использование необработанных указателей – Slava

+1

@krzaq '-O2' не имеет к этому никакого отношения, но версия GCC делает (с 6.0.0). Я не могу использовать GCC для нового, но это хороший аргумент, чтобы троллировать наших сопровождающих, чтобы переключиться на более новый. –

ответ

3

Я разработчик Cppcheck.

Мой проект также включает cppcheck в непрерывной интеграции, но он также не может его поднять.

интересная ошибка. Это ошибка, о которой cppcheck хочет предупредить. У нас есть некоторые связанные проверки, но это проскользнуло, к сожалению.

Неудивительно, учитывая характер регулярного выражения cppcheck.

Я лично не понимаю, почему некоторые люди говорят, что cppcheck является инструментом регулярных выражений.

Он использует AST, контекстно-зависимый анализ потока значений и т. Д. Для обнаружения ошибок. Так и GCC и Clang. Иногда Cppcheck считается инструментом регулярных выражений, но GCC и Clang - нет.

+1

FYI: Билет об этой проблеме уже создан http://trac.cppcheck.net/ticket/7812 – orbitcowboy

+3

Я признаю, что я не рассматривал внутренности cppcheck и, вероятно, получил впечатление, что это регулярное выражение, основанное на том, определены. Я удалил это замечание из вопроса, чтобы не распространять неправильную информацию. –