I have a warning I don’t understand in a templated function. How can the value be not initialized if its the if condition?
Note: the warning disappear if I remove std::vector<std::byte>
from the variant
My simplified code:
#include <cstdint>
#include <iostream>
#include <stdexcept>
#include <type_traits>
#include <variant>
#include <vector>
struct INOValue : std::variant<uint8_t, uint16_t, uint32_t, uint64_t, int64_t, std::vector<std::byte>>
{
using variant::variant;
};
template <typename T> constexpr T ToBiggerVariable( INOValue aVariable )
{
if constexpr( std::is_same<T, uint64_t>::value )
{
uint64_t lReturn = 0;
if ( auto *lPointer = std::get_if<uint8_t>( &aVariable ) )
{
lReturn = *lPointer;
}
else if( auto *lPointer2 = std::get_if<uint16_t>( &aVariable ) )
{
lReturn = *lPointer2;
}
else if( auto *lPointer3 = std::get_if<uint32_t>( &aVariable ) )
{
lReturn = *lPointer3;
}
else if( auto *lPointer4 = std::get_if<uint64_t>( &aVariable ) )
{
lReturn = *lPointer4;
}
else
{
throw std::logic_error( "Invalid conversion to uint64" );
}
return lReturn;
}
else
{
throw std::logic_error( "Type not handled" );
}
}
int main()
{
INOValue lValue = uint64_t( 12345 );
const uint64_t lValue2 = ToBiggerVariable<uint64_t>( lValue );
if( lValue2 > 0 )
std::cout << "OK";
return 0;
}
I have the same warning for lPointer2 and lPointer3
Warning ‘*(unsigned int*)((char*)&<unnamed> + offsetof(INOValue, INOValue::<unnamed>.std::variant<unsigned char, short unsigned int, unsigned int, long unsigned int, long int, std::vector<std::byte, std::allocator<std::byte> > >::<unnamed>.std::__detail::__variant::_Variant_base<unsigned char, short unsigned int, unsigned int, long unsigned int, long int, std::vector<std::byte, std::allocator<std::byte> > >::<unnamed>.std::__detail::__variant::_Move_assign_base<false, unsigned char, short unsigned int, unsigned int, long unsigned int, long int, std::vector<std::byte, std::allocator<std::byte> > >::<unnamed>.std::__detail::__variant::_Copy_assign_base<false, unsigned char, short unsigned int, unsigned int, long unsigned int, long int, std::vector<std::byte, std::allocator<std::byte> > >::<unnamed>.std::__detail::__variant::_Move_ctor_base<false, unsigned char, short unsigned int, unsigned int, long unsigned int, long int, std::vector<std::byte, std::allocator<std::byte> > >::<unnamed>.std::__detail::__variant::_Copy_ctor_base<false, unsigned char, short unsigned int, unsigned int, long unsigned int, long int, std::vector<std::byte, std::allocator<std::byte> > >::<unnamed>.std::__detail::__variant::_Variant_storage<false, unsigned char, short unsigned int, unsigned int, long unsigned int, long int, std::vector<std::byte, std::allocator<std::byte> > >::_M_u))’ may be used uninitialized [-Wmaybe-uninitialized]
My CMakelists if its useful:
cmake_minimum_required(VERSION 3.16)
project(test_init
LANGUAGES CXX
)
if(MSVC)
add_compile_options(/W4)
add_compile_options(/we4706 /we4275) #Assignement in if && dll link
else(MSVC)
set(cxx_flags -Wsuggest-override -Werror=suggest-override)
add_compile_options(-Wall -Wextra -Wpedantic -Wno-unknown-pragmas)
endif(MSVC)
add_executable(test_init main.cpp)
set_target_properties(test_init PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED YES
CXX_EXTENSIONS NO
)