I am using -Werror=uninitialized
locally in g++ args. It prevents me from bugs like this
int x;
++x;
But today I realized that my typical code of dfs on tree passes this check
vector<int> tin(n);
int tn;
function<void(int, int)> go = [&](int v, int p) {
tin[v] = tn++;
...
};
So after playing with lines of code I came to this successfully compiled code
int n = 100;
vector<vector<int>> g(n);
int tn;
++tn; //HELLO WHERE IS MY CE???
function<void()> f = [&] {
cout << tn << endl;
};
f();
What interesting is that commenting vector g
will result a compilation error. Replacing std::function
to lambda will result a compilation error. Moving g
under ++tn
will result a compilation error...
I am very tilted now. Mike please add g++14 with "deducing this" support...
Another reason why opaque abstractions like std::function are bad if used without a reason. However I don't think C++23 will be added any time soon (I've been petitioning for deducing this for quite long).
By the way, to avoid these bugs I never declare variables without initializing them. If you still want to do this,
-ftrivial-auto-var-init=pattern
makes them more visible (via a WA instead of uninitialized variables). Relevant documentation: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-ftrivial-auto-var-initAs far as the original issue goes, I think it's because of GCC not reasoning correctly about proper initialization (or some weird memory clobbering/laundering happening under the hood with std::function).
Thanks!
I recommend
-fsanitize=undefined
.Also you can report this as a bug, if it or something similar hasn't been reported yet.
in my example it does nothing: no warnings, compiled successful (arch, g++14.2.1)
What happened when it ran? Sanitizers work at runtime.
it just print garbage from tn, but not random. without fsanitize value is random each run.
UPD. following code compiles with fsanitize and fails without.
If something shouldn't succeed and it succeeds, that's still a bug.