On Mon, 2 Sept 2024 at 18:03, James K. Lowden <jklowden@xxxxxxxxxxxxxxx> wrote: > > I am experiencing problems that appear to be in std::variant. I wonder > if this has been reported before, and I just need to upgrade. > > The problem appears to be in this switch: > > class number_t { > enum type_t { int_e, float_e }; > std::variant<ssize_t, double> value; > public: > ... > number_t& operator=( const number_t& that ) { > assert( that.value.index() != std::variant_npos ); > switch( type_t(that.value.index()) ) { > case int_e: value = std::get<ssize_t>(that.value); break; > case float_e: value = std::get<double>(that.value); break; > } > return *this; > } > > That's not how I wrote the code originally. That's a re-write to try to isolate the problem. > > valgrind reports: > > ==999106== Conditional jump or move depends on uninitialised value(s) > ==999106== at 0x1130B8: number_t::operator=(number_t const&) (expression.h:80) > ==999106== by 0x123C23: env_t::numop(number_t& (*)(number_t&, exp_t const&), exp_t const&) (core.cc:429) > ==999106== by 0x123FA3: env_t::mul(exp_t const&, env_t&) (core.cc:457) > ==999106== by 0x12286F: env_t::eval(exp_t const&, env_t&) (core.cc:148) > ==999106== by 0x122767: env_t::eval(exp_t const&, env_t&) (core.cc:136) > ==999106== by 0x1104EB: yyparse() (parse.y:319) > ==999106== by 0x12DF3F: repl() (main.cc:30) > ==999106== by 0x12E20F: main (main.cc:79) > > It seems to me that if the assert doesn't trip, then the object must be initialized, in which case the switch cannot depend on an uninitialized value. I don't think your assumption is valid. If the variant's _M_index value is uninitialized, then the assert could pass because the index could be any garbage value. Is the RHS of the assignment (the object that the 'that' reference is bound to) correctly initialized? Are you sure?