CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 19

Thread: extern in macro

  1. #1
    Join Date
    Aug 2006
    Posts
    231

    extern in macro

    I'm using a library that provides some macros that adds overrided methods, etc.

    Code:
    #include "lib.h"
    
    class MyClass : public LibBase
    {
        MACRO( MyClass )
    };
    This works fine, but I would like to put MyClass into a namespace.

    Code:
    namespace mynamespace
    {
        class MyClass : public LibBase
        {
            MACRO( MyClass )
        };
    }
    The problem is that inside the macro, there is a line like:
    Code:
    extern LibClass var;
    Now, this adds a declaration to the namesspace, resulting in an error (unresolved external symbol "LibClass mynamespace::var").

    Is it possible to make mynamespace::var refer to (or be an alias for) the global namespace var?

    Or can you suggest some workaround?
    Last edited by TubularX; July 22nd, 2017 at 05:07 AM.

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: extern in macro

    Have you tried
    Code:
    extern LibClass ::var;
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    Join Date
    Aug 2006
    Posts
    231

    Re: extern in macro

    Thanks 2kaud!!

    Yes, the solution was to have both "extern LibClass var;" and "extern LibClass ::var;" inside the namespace.

    Hmm.. but how/why does that work?

    Visual Studio's Intellisense shows them as "var" and "mynamespace::var", as if they were two different variables. Of course, there's only one definition. However, if someone later defines a variable "var" inside the namespace, that one would suddenly be referenced instead, right?

  4. #4
    Join Date
    Oct 2008
    Posts
    1,456

    Re: extern in macro

    uhm, I don't think that's a portable solution ... it seems a VS non standard extension

  5. #5
    Join Date
    Aug 2006
    Posts
    231

    Re: extern in macro

    Quote Originally Posted by superbonzo View Post
    uhm, I don't think that's a portable solution ... it seems a VS non standard extension
    Bummer. Can anyone confirm?

    Is there any other solution to my problem?

  6. #6
    Join Date
    Oct 2008
    Posts
    1,456

    Re: extern in macro

    Quote Originally Posted by TubularX View Post
    Bummer. Can anyone confirm?
    if your current solution is something like

    Code:
    int var;
    namespace n {
    	extern int var;
    	extern int ::var;
    
    	int foo(){ return var; }
    }
    int main(){ n::foo(); }
    then I confirm it doesn't compile in my copy of gcc and clang. As far as I recall, a simple declarator cannot be qualified ( in fact, both compilers complain at "::var" )

    Quote Originally Posted by TubularX View Post
    Is there any other solution to my problem?
    can you post the macro definition ? ( or something equivalent yet complete ? )
    Last edited by superbonzo; July 22nd, 2017 at 08:16 AM. Reason: typos

  7. #7
    Join Date
    Aug 2006
    Posts
    231

    Re: extern in macro

    Quote Originally Posted by superbonzo View Post
    if your current solution is something like

    Code:
    int var;
    namespace n {
    	extern int var;
    	extern int ::var;
    
    	int foo(){ return var; }
    }
    int main(){ n::foo(); }
    No, that code doesn't compile in Visual Studio either.

    At least in VS, the order is important. It only works like this:

    Code:
    int var;
    namespace n {
    	extern int ::var;
    	extern int var;
    
    	int foo(){ return var; }
    }
    int main(){ n::foo(); }
    I don't have Microsoft extensions enabled. I compile with the /Za compiler option (emits an error for language constructs that are not compatible with ANSI C89 or ISO C++11).

    So, if this is not standard behaviour, it must be a bug in the compiler...?

  8. #8
    Join Date
    Aug 2006
    Posts
    231

    Re: extern in macro

    Quote Originally Posted by superbonzo View Post
    can you post the macro definition ? ( or something equivalent yet complete ? )
    OK, so here's some simplified code of my scenario:

    main.cpp
    Code:
    #include "lib.h"
    
    namespace n
    {
    	class MyClass : LibBase
    	{
    		MACRO_DECL( MyClass )
    	};
    
    	MACRO_DEF( MyClass )
    }
    
    int main()
    {
    	n::MyClass x;
    }

    lib.h
    Code:
    #ifndef include_guard
    #define include_guard
    
    class LibClass
    {
    public:
    	LibClass() {}
    };
    
    class LibBase
    {
    public:
    	LibBase( LibClass* ) {}
    };
    
    #define MACRO_DECL( name ) \
    public: \
    name(); \
    
    #define MACRO_DEF( name ) \
    extern LibClass* var; \
    name::name() : LibBase(var) {}
    
    extern LibClass* var;
    
    #endif
    lib.cpp

    Code:
    #include "lib.h"
    LibClass* var = nullptr;

  9. #9
    Join Date
    Oct 2008
    Posts
    1,456

    Re: extern in macro

    Quote Originally Posted by TubularX View Post
    At least in VS, the order is important. It only works like this:
    this does not compile either ( in clang ), and I'm pretty confident that it's non standard because simple declarators cannot be qualified names; I don't think it's bug though, probably it's just one of the many VS "convenience" feature ...

    Quote Originally Posted by TubularX
    OK, so here's some simplified code of my scenario:
    if you cannot change the lib code, nor the way it's used ( eg. define a global MyLibBase hiding the var passing mechanism ), nor intercept the code where the global var is set, the only workaround I can see is to manually link the extern var declared in mynamespace with the global one, via a linker script ( I don't known if VS linker can do that though ... )

  10. #10
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: extern in macro

    the only workaround I can see
    Just say 'Thank you MS' and comment the code that this is VS only.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  11. #11
    Join Date
    Aug 2006
    Posts
    231

    Re: extern in macro

    I came up with a solution that I believe will work in all compilers:

    Code:
    namespace n
    {
    	class MyClass : LibBase
    	{
    		MACRO_DECL( MyClass )
    	};
    }
    
    using n::MyClass;
    MACRO_DEF( MyClass )

  12. #12
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: extern in macro

    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  13. #13
    Join Date
    Oct 2008
    Posts
    1,456

    Re: extern in macro

    Quote Originally Posted by TubularX View Post
    I came up with a solution that I believe will work in all compilers:
    the problem is that it somewhat reduces the benefit of using a namespace in the first place ( that is, limiting name clashes ) ...

  14. #14
    Join Date
    Aug 2006
    Posts
    231

    Re: extern in macro

    Quote Originally Posted by superbonzo View Post
    the problem is that it somewhat reduces the benefit of using a namespace in the first place ( that is, limiting name clashes ) ...
    The code posted was just a simplified example.

    In the real codebase the lines

    using n::MyClass;
    MACRO_DEF( MyClass )

    will be put into a cpp file to limit the scope, so it's no problem.

  15. #15
    Join Date
    Oct 2008
    Posts
    1,456

    Re: extern in macro

    Quote Originally Posted by TubularX View Post
    will be put into a cpp file to limit the scope, so it's no problem.
    I understand, my point is that using-declarations do not hide names ( as declarations do at namespace scope ), they'll just raise a compiler error when a clashing name exists, eg, if your cpp includes some headers containing a clashing name at global scope; this would never happen when defining members in their own namespace ...

Page 1 of 2 12 LastLast

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