На недавней охоте за ошибками я обнаружил проблему с возвратом указателя на член временной переменной. Оскорбительный (упрощенный) код:Как предотвратить возврат указателя на временную переменную?
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
включен.
Если вы скомпилируете '-O2', gcc поймает эту ошибку: http://melpon.org/wandbox/permlink/KaXY4ktTM1vMNTiX – krzaq
« Как предотвратить это? » существует только одно решение - прекратить использование необработанных указателей – Slava
@krzaq '-O2' не имеет к этому никакого отношения, но версия GCC делает (с 6.0.0). Я не могу использовать GCC для нового, но это хороший аргумент, чтобы троллировать наших сопровождающих, чтобы переключиться на более новый. –