On Friday, 18 January 2019 16:16:07 UTC+2, Ralf Fassel wrote:
> This compiles w/o warnings or errors in g++ version 4.8.5 (Opensuse
> 42.3) and g++ 7.3.1 (Opensuse 15):
>
> #include <string>
> std::string func(std::string s) {
> return s;
> }
> int main(int argc, char **argv) {
> std::string s1 = func(s1);
> std::string s2(s2);
> std::string s3 = s3;
> return 0;
> }
>
> (and of course crashes at runtime...)
Formally the code is well formed, but reading objects before
construction is undefined behavior like reading objects
after destruction is undefined behavior. We may take
and pass references and pointers to such objects but not
to read.
Undefined behavior that always crashes is among best kind
of undefined behavior there is. What you complain?
>
> I would *at least* have expected some compiler diagnostics similar to e.g.
> int i = i;
> t.cc:7:11: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
Actually I get something like that from clang on your code:
warning: variable 's1' is uninitialized when used within its own initialization [-Wuninitialized]
Compilers have become very helpful these days.
> and in fact I would have expected an error along the lines "s1/s2/s3 is
> used before init".
>
> MSVC 2017 raises an error about s2 not being known, but if I comment
> that line out, it also compiles (and crashes)...
The C++ compiler vendors have put lot of effort into diagnosing
if the code is nonsensical. However in any useful language the
amount of different ways to express nonsense is endless. And
C++ is especially prone to that since language standard is
literally full of cases marked as "undefined behavior" (nonsense
that is not required to be diagnosed).