(Boost) Static Assert and behavior on msvc/gcc

Discussion in 'C++' started by Reetesh Mukul, Aug 6, 2009.

  1. 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
     
    Reetesh Mukul, Aug 6, 2009
    #1
    1. Advertising

  2. Reetesh Mukul wrote:
    > 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.
     
    Vladimir Jovic, Aug 6, 2009
    #2
    1. Advertising

  3. On 6 Aug, 17:56, Vladimir Jovic <> wrote:
    > Reetesh Mukul wrote:
    > > 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.


    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 ;).
     
    Reetesh Mukul, Aug 6, 2009
    #3
  4. Reetesh Mukul

    Greg Herlihy Guest

    On Aug 6, 5:16 am, Reetesh Mukul <> wrote:
    > 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
     
    Greg Herlihy, Aug 6, 2009
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Robert Brewer
    Replies:
    1
    Views:
    505
    bsmith
    Nov 7, 2004
  2. Thomas Guettler

    assert 0, "foo" vs. assert(0, "foo")

    Thomas Guettler, Feb 23, 2005, in forum: Python
    Replies:
    3
    Views:
    2,540
    Carl Banks
    Feb 23, 2005
  3. Replies:
    0
    Views:
    488
  4. Alex Vinokur

    assert(x) and '#define ASSERT(x) assert(x)'

    Alex Vinokur, Nov 25, 2004, in forum: C Programming
    Replies:
    5
    Views:
    937
    Keith Thompson
    Nov 25, 2004
  5. ImpalerCore

    To assert or not to assert...

    ImpalerCore, Apr 27, 2010, in forum: C Programming
    Replies:
    79
    Views:
    1,716
    Richard Bos
    May 17, 2010
Loading...

Share This Page