(Boost) Static Assert and behavior on msvc/gcc

R

Reetesh Mukul

Hello All,

I compiled the following code:-


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include <iostream>
#include <boost/static_assert.hpp>



namespace beta{

struct composition_root{};

template<typename composition>
struct composition_base: composition_root
{
private:
typedef composition C;
typedef typename C::alpha_type alpha_type;
typedef typename C::value_type value_type;

public:
const composition&
derived() const
{
return static_cast<const composition&>(*this);
}

composition&
derived()
{
return static_cast<composition&>(*this);
}

static alpha_type to_alpha(const value_type&)
{
BOOST_STATIC_ASSERT(false);
}

static value_type from_alpha(const alpha_type&)
{
BOOST_STATIC_ASSERT(false);
}
};

struct basic_composition_tag;
}


struct alpha_
{
typedef int alpha_type;
typedef char value_type;
char from_alpha(const alpha_type& x)
{

return 0;
}

int to_alpha(const value_type& x)
{
return 0;
}
};

int main(void)
{
typedef beta::composition_base<alpha_> a;
sizeof(a);
return 0;
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

on msvc(Version 9.0) and gcc 4.3.3.

Behavior:-
a) msvc -- compiles well
b) gcc -- throws error, basically assert failure

Even when I write,

int main(void)
{
//typedef beta::composition_base<alpha_> a;
//sizeof(a);
return 0;
}

The behavior is same.

$1. Is there any problem in BOOST_STATIC_ASSERT ? I will ask in boost
forum for it. Or else you know then please answer it.

$2. Why gcc is complaining error even when template instantiation has
not been done ? (second case)

$3. I understand that any direct use of compositon_base::{to/from }
_alpha is bound to cause problem. But if any code is not touching it,
in that case why compiler is throwing error.

$4. When does static function definition gets instantiated ? If in a
compilation unit, presence of a static function name and definition
anywhere (inside class or outside class) causes it to get instantiated
also, then does the gcc compiler is checking extra for a possible
error in instantiation of a composition_base class.

Please answer.

With Regards,
Reetesh Mukul
 
V

Vladimir Jovic

Reetesh said:
Hello All,

I compiled the following code:-


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include <iostream>
#include <boost/static_assert.hpp>



namespace beta{

struct composition_root{};

template<typename composition>
struct composition_base: composition_root
{
private:
typedef composition C;
typedef typename C::alpha_type alpha_type;
typedef typename C::value_type value_type;

public:
const composition&
derived() const
{
return static_cast<const composition&>(*this);
}

composition&
derived()
{
return static_cast<composition&>(*this);
}

static alpha_type to_alpha(const value_type&)
{
BOOST_STATIC_ASSERT(false);
}

static value_type from_alpha(const alpha_type&)
{
BOOST_STATIC_ASSERT(false);
}
};

struct basic_composition_tag;
}


struct alpha_
{
typedef int alpha_type;
typedef char value_type;
char from_alpha(const alpha_type& x)
{

return 0;
}

int to_alpha(const value_type& x)
{
return 0;
}
};

int main(void)
{
typedef beta::composition_base<alpha_> a;
sizeof(a);
return 0;
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

on msvc(Version 9.0) and gcc 4.3.3.

Behavior:-
a) msvc -- compiles well
b) gcc -- throws error, basically assert failure

Even when I write,

int main(void)
{
//typedef beta::composition_base<alpha_> a;
//sizeof(a);
return 0;
}

The conclusion: don't use microsoft crap
The behavior is same.

$1. Is there any problem in BOOST_STATIC_ASSERT ? I will ask in boost
forum for it. Or else you know then please answer it.

No, it works fine.
$2. Why gcc is complaining error even when template instantiation has
not been done ? (second case)

Because the compilation fails. And it fails because you are doing this:
BOOST_STATIC_ASSERT( false );
in your code.
$3. I understand that any direct use of compositon_base::{to/from }
_alpha is bound to cause problem. But if any code is not touching it,
in that case why compiler is throwing error.

Have you checked the BOOST_STATIC_ASSERT source code and the reference
manual? It is checking statically during the compilation whether it
passed or not. For example:
BOOST_STATIC_ASSERT( 4 == sizeof( int ) );
on some systems this will fail
$4. When does static function definition gets instantiated ? If in a
compilation unit, presence of a static function name and definition
anywhere (inside class or outside class) causes it to get instantiated
also, then does the gcc compiler is checking extra for a possible
error in instantiation of a composition_base class.

The use of BOOST_STATIC_ASSERT() is to statically check something during
the compilation.
 
R

Reetesh Mukul

The conclusion: don't use microsoft crap



No, it works fine.


Because the compilation fails. And it fails because you are doing this:
BOOST_STATIC_ASSERT( false );
in your code.


Have you checked the BOOST_STATIC_ASSERT source code and the reference
manual? It is checking statically during the compilation whether it
passed or not. For example:
BOOST_STATIC_ASSERT( 4 == sizeof( int ) );
on some systems this will fail


The use of BOOST_STATIC_ASSERT() is to statically check something during
the compilation.

Thanks Vladimir. I just read documentation of BOOST_STATIC_ASSERT,
http://www.boost.org/doc/libs/1_39_0/doc/html/boost_staticassert.html.
And looked into the section:- "Use in templates". Looks like this
behavior is more related to gcc. But I will not wish to call msvc
crap ;).
 
G

Greg Herlihy

Hello All,

I compiled the following code:-

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include <iostream>
#include <boost/static_assert.hpp>

namespace beta{

        struct composition_root{};

        template<typename composition>
        struct composition_base: composition_root
        {
        private:
                typedef composition C;
                typedef typename C::alpha_type alpha_type;
                typedef typename C::value_type value_type;

        public:
...
                static alpha_type to_alpha(const value_type&)
                {
                        BOOST_STATIC_ASSERT(false);
                }

                static value_type from_alpha(const alpha_type&)
                {
                        BOOST_STATIC_ASSERT(false);
                }
        };

        struct basic_composition_tag;

}

};

int main(void)
{
        typedef beta::composition_base<alpha_> a;
        sizeof(a);
        return 0;
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

on msvc(Version 9.0) and gcc 4.3.3.

Behavior:-
a) msvc -- compiles well
b) gcc -- throws error, basically assert failure

The behavior is same.

$1. Is there any problem in BOOST_STATIC_ASSERT ? I will ask in boost
forum for it. Or else you know then please answer it.

There are limitations in implementing a static_assert with a macro
(which is why static_assert has been added to the next C++ Standard).
Namely, the compiler will not necessarily defer evaluating the macro
static assert until the template is instantiated.
$2. Why gcc is complaining error even when template instantiation has
not been done ? (second case)

The g++ compiler parses the template body and detects an error that
would prevent the template from ever being instantiated. To prevent g+
+ from processing the boost static_assert before the template is
instantiated, make the assert type-dependent:

static value_type from_alpha(const alpha_type&)
{
BOOST_STATIC_ASSERT(sizeof(composition) == 0);
}

Greg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top