#include <iostream>
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
class A {
public:
fs::path path_;
const fs::path & path() const { return path_; }
fs::path & path() { return path_; }
};
class B {
public:
fs::path root_path_;
A path_2;
A path_3;
const fs::path & operator()() const {
for ( const auto & path : {
path_3.path(),
path_2.path(),
root_path_
}) {
if ( not path.empty() ) {
return path;
}
}
throw std::logic_error{"using default-constructed B"};
}
};
int main(int argc, char **argv) {
B b;
b.root_path_ = "foo/";
b.path_2.path() = "foo/bar";
b.path_3.path() = "foo/baz";
std::cout << b() << '\n';
return 0;
}
With the above code, which as far as I know seems to be valid C ++. Instead, when I call, I get garbage output.
g++Don't complain initially, however the Sanitizer address does. g++finally complains when adding -O2. Created Alert
test.cpp: In member function ‘const boost::filesystem::path& B::operator()() const’:
test.cpp:31:12: warning: function may return address of local variable [-Wreturn-local-addr]
return path;
^~~~
test.cpp:29:3: note: declared here
}) {
^
Please note that I use:
$ cat /etc/fedora-release
Fedora release 25 (Twenty Five)
$ g++ --version
g++ (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1)
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Note that I resolved the error by specifying a pointer instead.
const fs::path & operator()() const {
for ( const auto * path : {
&path_3.path(),
&path_2.path(),
&root_path_
}) {
if ( not path->empty() ) {
return *path;
}
}
throw std::logic_error{"using default-constructed B"};
}
But that leaves me with a few questions:
- Why
g++doesn't he complain about the problem until it is added -O2? - undefined? , :
B::operator() const - ... ... const. , , , , . -. const auto &, ... const member. , ?