CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    namespace expert needed :-(

    I'm building some code which has a lot of stuff in namespace Akupara. I've no idea what the word 'Akupara' actually means - but the namespace arrangement seems to be giving me a weird problem. Consider the following source modules (main.cpp / header_A.h / header_B.h). I've cut the code down to the minimum needed to reproduce the problem (the actual Akupara headers are quite a bit bigger than I've shown):-

    Code:
    // main.cpp
    #include "header_A.h"
    //#include "header_B.h"
    
    int main (int argc, char *argv[])
    {
    	return 0;
    }
    Code:
    // header_A.h
    #if !defined(_HEADER_A_INCLUDED_)
    #define _HEADER_A_INCLUDED_
    
    #ifndef __int8_t_defined
    #define __int8_t_defined
    typedef          __int8  int8_t;
    typedef unsigned __int8  uint8_t;
    typedef          __int16 int16_t;
    typedef unsigned __int16 uint16_t;
    typedef          __int32 int32_t;
    typedef unsigned __int32 uint32_t;
    typedef          __int64 int64_t;
    typedef unsigned __int64 uint64_t;
    #endif
    
    namespace Akupara
    {
    	namespace detail
    	{
    		template<unsigned int _size, bool _signed> 
    		struct integer_with_byte_count_base;
    
    		template<>
    		struct integer_with_byte_count_base<1,true> { typedef int8_t  type; };
    
    		template<>
    		struct integer_with_byte_count_base<2,true> { typedef int16_t type; };
    
    		template<>
    		struct integer_with_byte_count_base<4,true> { typedef int32_t type; };
    
    		template<>
    		struct integer_with_byte_count_base<8,true> { typedef int64_t type; };
    
    		template<>
    		struct integer_with_byte_count_base<1,false> { typedef uint8_t  type; };
    
    		template<>
    		struct integer_with_byte_count_base<2,false> { typedef uint16_t type; };
    
    		template<>
    		struct integer_with_byte_count_base<4,false> { typedef uint32_t type; };
    
    		template<>
    		struct integer_with_byte_count_base<8,false> { typedef uint64_t type; };
    	} // namespace detail
    
    	template<unsigned int _size, bool _signed=true>
    	struct integer_with_byte_count : public detail::integer_with_byte_count_base<_size,_signed>
    	{
    		typedef typename detail::integer_with_byte_count_base<_size,_signed>::type type;
    		static const bool s_correct_size = compiletime_assert<sizeof(type)==_size>::value;
    	};
    
    	template<unsigned int _size>
    	struct signed_integer_with_byte_count : public integer_with_byte_count<_size,true> {};
    
    	template<unsigned int _size>
    	struct unsigned_integer_with_byte_count : public integer_with_byte_count<_size,false> {};
    
    	template<typename _T, _T _v>
    	struct integral_constant
    	{
    		static const _T                    value = _v;
    		typedef _T                         value_type;
    		typedef integral_constant<_T, _v>  type;
    	}; // struct integral_constant
    	typedef integral_constant<bool, false> false_type;
        typedef integral_constant<bool, true > true_type;
    } // namespace Akupara
    
    #endif // _HEADER_A_INCLUDED_
    Code:
    // header_B.h
    #if !defined(_HEADER_B_INCLUDED_)
    #define _HEADER_B_INCLUDED_
    
    namespace Akupara
    {
        namespace threading
        {
            namespace atomic
            {
                namespace machine
                {
                    template<unsigned int _byte_count> struct implements_load  : public false_type {};
                    template<unsigned int _byte_count> struct implements_store : public false_type {};
                } // namespace machine
            } // namespace atomic
        } // namespace threading
    } // namespace Akupara
    
    
    namespace Akupara
    {
        namespace threading
        {
            namespace atomic
            {
                namespace detail
                {
                    template<unsigned int _byte_count> 
                    struct largest_atomic_byte_count_upto 
                    { 
                        static const unsigned int value = 
                            machine::implements_load<_byte_count>::value && machine::implements_store<_byte_count>::value ? _byte_count
    						: largest_atomic_byte_count_upto<_byte_count/2>::value; 
                    };
    
                    template<> 
                    struct largest_atomic_byte_count_upto<0> { static const unsigned int value = 0; };
    
                    const unsigned int k_byte_count_best_atomic = largest_atomic_byte_count_upto<sizeof(int)>::value;
                } // namespace detail
    
                typedef   signed_integer_with_byte_count< detail::k_byte_count_best_atomic >::type signed_integer_type;
                typedef unsigned_integer_with_byte_count< detail::k_byte_count_best_atomic >::type unsigned_integer_type;
                typedef signed_integer_type integer_type;
            } // namespace atomic
        } // namespace threading
    } // namespace Akupara
    
    #endif // _HEADER_B_INCLUDED_
    If I build main.cpp exactly as shown (i.e. with header_B.h commented out) it builds absolutely fine. However, if I uncomment the inclusion of header_B.h I suddenly get errors in header_A.h (even though header_A.h gets included before header_B.h!! As soon as I #include "header_B.h" I get this error at the red line in header_A.h:-

    error C2504: 'Akupara:etail::integer_with_byte_count_base<_size,_signed>' : base class undefined
    OTOH if I #include "header_B.h" - BUT - I comment out the blue lines, the error goes away. There must be some weird interaction between the two header files but I'm totally baffled. Is it something to do with namespaces?
    Last edited by John E; May 2nd, 2014 at 12:39 AM. Reason: typdefs added to the top of header_A.h
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  2. #2
    Join Date
    Nov 2003
    Posts
    1,902

    Re: namespace expert needed :-(

    Why doesn't header_B.h include header_A.h since it depends on it? (forgive me for not compiling it myself...)
    What VC++ version is this?

    gg

  3. #3
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: namespace expert needed :-(

    Quote Originally Posted by Codeplug View Post
    Why doesn't header_B.h include header_A.h since it depends on it
    Actually, in the original code it does (remember that I've stripped a lot of stuff out, to make the problem easier to reproduce).

    Quote Originally Posted by Codeplug View Post
    What VC++ version is this?
    That would have been my next question! For corporate reasons we're still using VC8 (although to be fair, it's been a pretty good compiler up to now). But my next question would be to ask if some kind soul can try building these modules with a more recent version of MSVC? I might be wrong but I've a sneaking suspicion that I might have unearthed a compiler bug here.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  4. #4
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: namespace expert needed :-(

    Quote Originally Posted by John E View Post
    For corporate reasons we're still using VC8 (although to be fair, it's been a pretty good compiler up to now). But my next question would be to ask if some kind soul can try building these modules with a more recent version of MSVC? I might be wrong but I've a sneaking suspicion that I might have unearthed a compiler bug here.
    Compiles fine in VC9.
    What is the complete error message you get?
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  5. #5
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: namespace expert needed :-(

    Quote Originally Posted by D_Drmmr View Post
    Compiles fine in VC9.
    What is the complete error message you get?
    Here's the full build output (the first error is at that line I marked in red):-

    1>------ Build started: Project: MSVCtest_app, Configuration: Debug Win32 ------
    1>Compiling...
    1>main.cpp
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(50) : error C2504: 'Akupara:etail::integer_with_byte_count_base<_size,_signed>' : base class undefined
    1> with
    1> [
    1> _size=0,
    1> _signed=true
    1> ]
    1> f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(56) : see reference to class template instantiation 'Akupara::integer_with_byte_count<_size,_signed>' being compiled
    1> with
    1> [
    1> _size=0,
    1> _signed=true
    1> ]
    1> f:\+gtk-sources\mixbus3\msvctest_app\header_B.h(43) : see reference to class template instantiation 'Akupara::signed_integer_with_byte_count<_size>' being compiled
    1> with
    1> [
    1> _size=0
    1> ]
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(51) : error C2027: use of undefined type 'Akupara:etail::integer_with_byte_count_base<_size,_signed>'
    1> with
    1> [
    1> _size=0,
    1> _signed=true
    1> ]
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(51) : error C2146: syntax error : missing ';' before identifier 'type'
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(51) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(51) : error C2602: 'Akupara::integer_with_byte_count<_size,_signed>::type' is not a member of a base class of 'Akupara::integer_with_byte_count<_size,_signed>'
    1> with
    1> [
    1> _size=0,
    1> _signed=true
    1> ]
    1> f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(51) : see declaration of 'Akupara::integer_with_byte_count<_size,_signed>::type'
    1> with
    1> [
    1> _size=0,
    1> _signed=true
    1> ]
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(51) : error C2868: 'Akupara::integer_with_byte_count<_size,_signed>::type' : illegal syntax for using-declaration; expected qualified-name
    1> with
    1> [
    1> _size=0,
    1> _signed=true
    1> ]
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(52) : error C2065: 'compiletime_assert' : undeclared identifier
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(52) : error C2039: 'value' : is not a member of '`global namespace''
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(52) : error C2065: 'value' : undeclared identifier
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(52) : error C2866: 'Akupara::integer_with_byte_count<_size,_signed>::s_correct_size' : a const static data member of a managed type must be initialized at the point of declaration
    1> with
    1> [
    1> _size=0,
    1> _signed=true
    1> ]
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(50) : error C2504: 'Akupara:etail::integer_with_byte_count_base<_size,_signed>' : base class undefined
    1> with
    1> [
    1> _size=0,
    1> _signed=false
    1> ]
    1> f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(59) : see reference to class template instantiation 'Akupara::integer_with_byte_count<_size,_signed>' being compiled
    1> with
    1> [
    1> _size=0,
    1> _signed=false
    1> ]
    1> f:\+gtk-sources\mixbus3\msvctest_app\header_B.h(44) : see reference to class template instantiation 'Akupara::unsigned_integer_with_byte_count<_size>' being compiled
    1> with
    1> [
    1> _size=0
    1> ]
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(51) : error C2027: use of undefined type 'Akupara:etail::integer_with_byte_count_base<_size,_signed>'
    1> with
    1> [
    1> _size=0,
    1> _signed=false
    1> ]
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(51) : error C2146: syntax error : missing ';' before identifier 'type'
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(51) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(51) : error C2602: 'Akupara::integer_with_byte_count<_size,_signed>::type' is not a member of a base class of 'Akupara::integer_with_byte_count<_size,_signed>'
    1> with
    1> [
    1> _size=0,
    1> _signed=false
    1> ]
    1> f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(51) : see declaration of 'Akupara::integer_with_byte_count<_size,_signed>::type'
    1> with
    1> [
    1> _size=0,
    1> _signed=false
    1> ]
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(51) : error C2868: 'Akupara::integer_with_byte_count<_size,_signed>::type' : illegal syntax for using-declaration; expected qualified-name
    1> with
    1> [
    1> _size=0,
    1> _signed=false
    1> ]
    1>f:\+gtk-sources\mixbus3\msvctest_app\header_A.h(52) : error C2866: 'Akupara::integer_with_byte_count<_size,_signed>::s_correct_size' : a const static data member of a managed type must be initialized at the point of declaration
    1> with
    1> [
    1> _size=0,
    1> _signed=false
    1> ]
    1>Build log was saved at "file://f:\+GTK-SOURCES\Mixbus3\MSVCtest_app\Debug\BuildLog.htm"
    1>MSVCtest_app - 17 error(s), 0 warning(s)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    [Edit...] It seems to be expecting some base class templates where _size == 0 (but I don't understand why )
    Last edited by John E; May 2nd, 2014 at 02:27 AM.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  6. #6
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: namespace expert needed :-(

    Quote Originally Posted by John E View Post
    It seems to be expecting some base class templates where _size == 0 (but I don't understand why )
    That's because there is no specialization for 'implements_load' and 'implements_store'. Don't know if you removed this to get a minimal example or if they are missing in your actual code (maybe the configuration of the library has gone wrong).

    What's happening is that the line
    Code:
    const unsigned int k_byte_count_best_atomic = largest_atomic_byte_count_upto<sizeof(int)>::value;
    is doing some template metaprogramming to find the largest byte count (as a power of 2) no larger than sizeof(int) for which 'implements_load' and 'implements_store' are specialized to derive from true_type. Since there is no such specialization, the line above reduces to the specialization
    Code:
    template<> 
    struct largest_atomic_byte_count_upto<0> { static const unsigned int value = 0; };
    which explains why the compiler is trying to instantiate 'signed_integer_with_byte_count<0>'.

    Edit: if I include "header_B.h" in main, I get the same error message in VC9.
    Last edited by D_Drmmr; May 2nd, 2014 at 03:44 AM.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  7. #7
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: namespace expert needed :-(

    Quote Originally Posted by D_Drmmr View Post
    That's because there is no specialization for 'implements_load' and 'implements_store'. Don't know if you removed this to get a minimal example or if they are missing in your actual code (maybe the configuration of the library has gone wrong)
    Wow, thanks for the info!

    I found one other header file which contains the text "implements_load" and "implements_store". In cut-down form it looks like this:-

    Code:
    // header_C.h
    namespace Akupara
    {
    	namespace threading
    	{
    		namespace atomic
    		{
    			namespace machine
    			{
    				const unsigned int k_bytes_per_cache_line = 64;  // this is true for P4 & K8
    	
    
    				// Flags for operations supported by this machine
    				//-------------------------------------
    				template<> struct implements_load         <4> : public true_type {};
    				template<> struct implements_store        <4> : public true_type {};
    
    				// [...]
    					
    				// Some other stuff - but no more references
    				// to 'implements_load' or 'implements_store'
    
    			} // namespace machine
    		} // namespace atomic
    	} // namespace threading
    } // namespace Akupara
    However, if I modify header_B.h so that it now #includes header_C.h, unfortunately that doesn't fix the problem. Maybe this library's got some source files missing? What would you expect those specializations to look like? (just roughly)
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  8. #8
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: namespace expert needed :-(

    FYI:
    akupara is the name of "the world turtle", the turtle that carries the 16 white elefants on it's back which in turn carry the world on their backs according to hindy mythology.

    it's meaning is also "unbounded" which might make sense in some library context.

    then again, it could just be the name of the company that made the lib.

  9. #9
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: namespace expert needed :-(

    looks like it'll need a
    Code:
    Akupara::threading::atomic::detail::machine::implements_load<X>
    with X being 1, 2, 4, or 8.


    change C to have an extra detail namespace between 'atomic' and 'machine'

    it doesn't really make much sense that way though, my guess it's an error in B where they implemented the template in the detail namespace incorrectly.

  10. #10
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: namespace expert needed :-(

    I spent a couple of hours experimenting this morning but even after following the suggestions here, I couldn't come up with anything that would compile. One thing that puzzled me was this code from header_B.h:-

    Code:
                    template<unsigned int _byte_count> 
                    struct largest_atomic_byte_count_upto 
                    { 
                        static const unsigned int value = 
                            machine::implements_load<_byte_count>::value && machine::implements_store<_byte_count>::value ? _byte_count
    						: largest_atomic_byte_count_upto<_byte_count/2>::value; 
                    };
    To me, this implies that the structs / specializations for implements_load and implements_store are expected to have a member called value. But I couldn't see any evidence that they do. I even tried adding one - but that didn't help either...

    The actual library is intended to be a set of "atomic ops" - i.e. functions for manipulating integers atomically. I think I'll just cut my losses and use some other library.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  11. #11
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: namespace expert needed :-(

    Quote Originally Posted by John E View Post
    To me, this implies that the structs / specializations for implements_load and implements_store are expected to have a member called value. But I couldn't see any evidence that they do. I even tried adding one - but that didn't help either...
    Yes, that's what the derivation from false_type or true_type do.
    both of which are derived from constant_integral which has the value.

    The actual library is intended to be a set of "atomic ops" - i.e. functions for manipulating integers atomically. I think I'll just cut my losses and use some other library.
    I haven't looked at getting this into an actual compiler yet, since I don't have one handy where I'm at.
    but it seems somewhat elaborate for atomic operations.

    for Windows, and at low level you have the interlockedXXX family of functions to do that,
    and if you want to be more portable, there's <atomic> header you can include (C++11)
    if you can't do C++11
    boost has a nice alternative.

  12. #12
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: namespace expert needed :-(

    Thanks O'Reubens. The other possibility is Glib (from the GTK+ project). Our own project already uses Glib so with a bit of luck, that might hopefully be simpler than implementing all this Akupara stuff...
    "A problem well stated is a problem half solved.” - Charles F. Kettering

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured