On Wed, 2023-12-20 at 11:16 -0800, Eric Batchelor wrote: > Hello, I unintentionally stumbled upon some strange behaviour that > occurred due to a typo. > I reproduced the behaviour where an object (std::string in my case) > can > be passed to a function by reference, uninitialized, WITHOUT a > compiler > warning. > Changing the code to pass the object by value DOES emit the warning. > I don't think the compiled code is incorrect, it segfaults presumably > due to uninitialized members. > I understand there may seldom be a reason to use uninitialized > objects, > so "don't do that," but as I said this was unintentional and it seems > that it should have generated a warning, which have saved some > head-scratching. > > Code to reproduce: > > #include <string> > std::string f(std::string &s) { > s.append("x"); > return s; > } > int main() { > std::string a = f(a); > } > > Compile and run (no warning): > > $ g++ -o uninit_obj uninit_obj.cpp -std=c++23 -Wall -Wpedantic - > Wextra > && ./uninit_obj > Segmentation fault (core dumped) > > No difference whether using -O0 (or 1 2 3)
As I understand it, -Wmaybe-uninitialized is purely intraprocedural i.e. it works within each individual function, without considering the interactions *between* functions. FWIW, -fanalyzer does attempt to model interprocedural interactions, but doesn't yet work properly on C++ code. For your example, it happens to generate some warnings, but the wording is really vague; see: https://godbolt.org/z/a1q7xYMjb and it might well be getting other things wrong (as I said, it doesn't yet properly work on C++). Dave > > If I change the function to pass by value, std::string f(std::string > s), > and rerun, I get the expected compiler warning: > > $ g++ -o uninit_obj uninit_obj.cpp -std=c++23 -Wall -Wpedantic - > Wextra > && ./uninit_obj > uninit_obj.cpp: In function 'int main()': > uninit_obj.cpp:7:22: warning: 'a' may be used uninitialized > [-Wmaybe-uninitialized] > 7 | std::string a = f(a); > [...] > terminate called after throwing an instance of 'std::bad_alloc' > what(): std::bad_alloc > Aborted (core dumped) > > Output from g++ -v: > > Using built-in specs. > COLLECT_GCC=g++ > COLLECT_LTO_WRAPPER=/usr/local/gcc13/libexec/gcc/x86_64-pc-linux- > gnu/13.2.0/lto-wrapper > Target: x86_64-pc-linux-gnu > Configured with: ../gcc-13.2.0/configure --disable-multilib > --enable-languages=c,c++ --prefix=/usr/local/gcc13 --program-suffix=- > 13 > --enable-libstdcxx-backtrace=yes > Thread model: posix > Supported LTO compression algorithms: zlib > gcc version 13.2.0 (GCC) > > Thanks >