含std::vector的std::variant引发GCC模板函数未初始化警告问题
关于std::variant模板函数中-Wmaybe-uninitialized警告的疑惑
在模板函数中遇到了无法理解的-Wmaybe-uninitialized警告,疑惑作为if判断条件的变量为何会被判定为可能未初始化。
注意:当从std::variant中移除std::vector<std::byte>类型时,该警告会消失。
简化后的代码
#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; }
警告信息
在lPointer2和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]
CMakeLists配置(供参考)
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 )
环境信息
- GCC版本:11.4.0(Ubuntu 11.4.0-1ubuntu1~22.04)
- 复现环境:WSL、基于Ubuntu 22.04的Docker容器
Dockerfile内容(省略OpenCV、Qt等特定安装项)
FROM ubuntu:22.04 RUN apt -y update && \ apt -y upgrade && \ apt-get -y install \ build-essential \ gdb \ ninja-build \ cmake \ wget \ unzip \ git \ python3 \ python3-pip \ curl \ cppcheck \ sudo
内容的提问来源于stack exchange,提问作者David Levy
相关产品推荐
相关产品推荐

