if constexpr and C4702 (and C4100, and C4715)

if constexpr and C4702 (and C4100, and C4715)



Is there a way to fix the following problem:



This code produces a C4702 warning 'unreachable code' (on VC++ 15.8 with /std:c++17)


/std:c++17


template <typename T, typename VariantType>
inline bool MatchMonostate( VariantType& variant )

SUPPRESS_C4100( variant );
if constexpr ( std::is_same_v<T, std::monostate> )

variant = std::monostate();
return true;

return false; // !!! unreachable if the above is true !!! => C4702



to suppress the C4100 'unreferenced formal parameter' warning, I'm already using the trick


#define SUPPRESS_C4100(x) ((void)x)



The simple idea of adding


else

return false;



results in warning C4715 'not all control paths return a value' instead.






You do not need the SUPRESS_C4100 "trick". See here: wandbox.org/permlink/zewgEt073tRV3dJV .. same is here on my machine with MSVC 19.15.26726

– user10133158
Sep 9 '18 at 23:23


SUPRESS_C4100






Thx for pointing this out. Just using bool MatchMonostate( [[maybe_unused]] VariantType& variant ) gets rid of C4100.

– old123987
Sep 10 '18 at 12:02


bool MatchMonostate( [[maybe_unused]] VariantType& variant )






yes that works too. Although latest releases of the "big three" do no need even that ...

– user10133158
Sep 10 '18 at 12:22






Not sure which is your 3rd. My VC++ 15.8.3 with /std:c++latest will issue C4100 without [[maybe_unused]]

– old123987
Sep 10 '18 at 15:34


[[maybe_unused]]






... I might be missing something .. please go to your devl command prompt and do "cl /Bv" .That gives the version nums. mine is 19.15.26726.0 ... I shall re-try in an empty project ...

– user10133158
Sep 11 '18 at 18:24


cl /Bv




2 Answers
2



It's unreachable because for a given expansion of the template based on the template arguments the function will only ever pass the condition and return true or fail and return false. There is no case where it could go either way for the same type. It's essentially expanding to


if (true)
return true;

return false; // Obviously will never happen



I'd rewrite it to only have a single return statement.


template <typename T, typename VariantType>
inline bool MatchMonostate( VariantType& variant )

SUPPRESS_C4100( variant );
bool retval = false;
if constexpr ( std::is_same_v<T, std::monostate> )

variant = std::monostate();
retval = true;

return retval;



Also, in the case where the condition is true variant is not unused. You may want to move that line that suppresses the warning (which basically turns into (void)variant) to an else statement.






Still, I would have thought, a modern compiler could figure this out by itself

– old123987
Sep 9 '18 at 12:58






@old123987 the compiler did figure it out and warned you that the line was unreachable. =P

– Moohasha
Sep 9 '18 at 12:59







You mean aside from answering the question? The question was about a line being unreachable. This answer explained why and corrected it.

– Moohasha
Sep 9 '18 at 21:36






@ChefGladiator Casting a thing to void to suppress 'unused variable' warning is widely used pre-C++17 (and in C). It's not standard, but I wouldn't say it's "as far as one can get from standard portable C++". As far as I know, it's fairly portable and should work on most decent compilers.

– HolyBlackCat
Sep 9 '18 at 21:59







Where did OP say he was trying to write portable code?

– Moohasha
Sep 9 '18 at 22:15



As the direct answer to the direct question. On the subject of if constexpr. Consider this:


if constexpr


template <typename T, typename ... params >
inline bool match_monostate
(std::variant<params ...> & variant) noexcept

if constexpr (std::is_same_v<T, std::monostate>)

variant = std::monostate ;
// compiles only if called with variant
// whose one alternative is std::monostate
return true;

else
return false;




Depending on the bool result of the if constexpr expression, compiler actually produces two functions. This version is produced when if constexpr() yields true:


if constexpr


if constexpr()


template <typename T, typename ... params >
inline bool
match_monostate (std::variant<params ...> & variant) noexcept

variant = std::monostate ;
// compiles only if called with variant
// whose one alternative is std::monostate
return true;



This version is produced when if constexpr() yields false:


if constexpr()


template <typename T, typename ... params >
inline bool
match_monostate (std::variant<params ...> & variant) noexcept

return false;



The second version might emit warnings about unused argument. But (it seems) not if using the latest versions of clang/gcc/msvc. For older compilers as "old123987" also pointed out one can add the standard attribute to the signature. Like so:


template <typename T, typename ... params >
inline bool
match_monostate ([[maybe_unused]] std::variant<params ...> & variant) ;



That will stop the warning emitting.






Do you see any upside/downside in using std::variant<params...>& vs just VariantType& ? (besides type safety)

– old123987
Sep 10 '18 at 15:42






I can not see any obvious downside to the match_monostate signature, as presented. It will also stop you doing for example this: match_monostate( variant<int>); or calling it with const instances ...

– user10133158
Sep 11 '18 at 7:17



match_monostate


match_monostate( variant<int>);






As an anti jokers measure you can delete this declaration: ` template <typename ... params > inline bool match_monostate ( std::variant<params ...> && variant) ; = delete, to stop them calling it with moved instances match_monostate( move(var_))`

– user10133158
Sep 11 '18 at 7:36



, to stop them calling it with moved instances



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)