Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a workaround for this C4702 link-time warning?

I'm using boost::variant and am having trouble compiling in release mode. I am working in VC2010 with warning level 4 and warnings as errors. The code below compiles fine in debug mode, but in release mode I get a bunch of "Unreachable code" C4702 warnings emitted at link time (presumably I'm getting compiler warnings here because there is link time code generation when optimisations are enabled.)

Has anybody successfully disabled these warnings in this situation? I would prefer to keep the high warning level and warnings as errors if possible.

#pragma warning( disable:4702 )

... doesn't seem to work here. Here is some sample code:

#include <boost/variant.hpp>

struct null{};
typedef boost::variant< null, double > variant_t;

class addition_visitor
: public boost::static_visitor< variant_t >
{
public:
    template< typename T, typename U >
    variant_t operator()( const T&, const U& ) const
    { 
        throw( "Bad types" );
    }

    variant_t operator()( const double& left, const double& right ) const
    {
        return variant_t( left * right );
    }
};

int main(int /*argc*/, char** /*argv*/)
{
    variant_t a( 3.0 ), b( 2.0 );
    variant_t c = boost::apply_visitor( addition_visitor(), a, b );
    return 0;
}

The warning is triggered by the templated operator(), which I'm using to catch attempts to apply the visitor to bad variant types.

like image 820
RobH Avatar asked Apr 01 '11 11:04

RobH


4 Answers

After a spot of lunch and a stroll, I've got an unsatisfying but functioning work-around. Instead of returning a variant from my visitor and throwing on error, I return a success boolean and store a result, thus:

#include <boost/variant.hpp>

struct null{};
typedef boost::variant< null, double > variant_t;

class addition_visitor
: public boost::static_visitor< bool >
{
public:
    template< typename T, typename U >
    bool operator()( const T&, const U& )
    { 
        //throw( "Bad types" );
        return false;
    }

    bool operator()( const double& left, const double& right )
    {
        result = variant_t( left * right );
        return true;
    }

    variant_t result;
};

int main(int /*argc*/, char** /*argv*/)
{
    variant_t a( 3.0 ), b( 2.0 );
    addition_visitor v;
    if( !boost::apply_visitor( v, a, b ) )
    {
        throw( "Bad types" );
    }

    variant_t c = v.result;
    return 0;
}
like image 92
RobH Avatar answered Nov 03 '22 00:11

RobH


Why provide a body for the template operator at all?

I haven't got Boost handy here so I can't check for you, but the fact that the templated operator has a body most probably means that any and all calls, regardless of type, will compile fine, then throw an error at runtime.

Leave the body of the template operator out, and it will simply refuse to link when used with any other type than double.

like image 42
Jaap Avatar answered Nov 03 '22 02:11

Jaap


The #pragma doesn't work because this is a link time not a compile time warning.

You could suppress the warning in release mode. I believe /ignore:xxxx on the linker command line will do the trick.

like image 34
Nathanael Avatar answered Nov 03 '22 01:11

Nathanael


I had a very similar problem in a Visual Studio 2012 MFC project; the same warning came from the <memory> header file, also during Release link time code generation.
I solved it by adding #pragma warning(disable:4702) early in the pre-compiled header file ("stdafx.h" in my case, just before #including STL header files).

like image 21
dan_din_pantelimon Avatar answered Nov 03 '22 01:11

dan_din_pantelimon