namespace and #define

Discussion in 'C++' started by lallous, Nov 2, 2004.

  1. lallous

    lallous Guest

    Hello

    I noticed that when I use #define inside a namespace then this #define only
    works when prefixed with the namespace name.

    Is this behaviour standard or just compiler specific?

    I use VC7.

    namespace test
    {
    #define X int
    };

    Now can be used as:

    test::X

    --
    Elias
     
    lallous, Nov 2, 2004
    #1
    1. Advertising

  2. lallous

    Sharad Kala Guest

    "lallous" <> wrote in message
    > Hello
    >
    > I noticed that when I use #define inside a namespace then this #define

    only
    > works when prefixed with the namespace name.
    >
    > Is this behaviour standard or just compiler specific?
    >
    > I use VC7.
    >
    > namespace test
    > {
    > #define X int
    > };


    There is no semicolon after a namespace definition.

    >
    > Now can be used as:
    >
    > test::X


    IMO, this is not correct behavior. Macros do replacement without taking
    account namespace rules etc. So macro should expand test::X to test::int
    which is non-sensical. Just using X should have been good.

    Sharad
     
    Sharad Kala, Nov 2, 2004
    #2
    1. Advertising

  3. lallous

    Sharad Kala Guest


    > So macro should expand test::X to test::int


    Replace macro with preprocessor.
     
    Sharad Kala, Nov 2, 2004
    #3
  4. "lallous" <> wrote in message
    news:...
    > I noticed that when I use #define inside a namespace then this #define
    > only works when prefixed with the namespace name.
    >
    > Is this behaviour standard or just compiler specific?

    Definitely not standard.
    And I think you misinterpreted what happened.

    > I use VC7.
    >
    > namespace test
    > {
    > #define X int
    > };
    >
    > Now can be used as:
    >
    > test::X


    No compiler should accept this, and I'm not familiar
    with any such extension in VC7 or elsewhere.
    Could you post the exact code that lead you to your conclusion?



    Regards,
    Ivan
    --
    http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
    Brainbench MVP for C++ <> http://www.brainbench.com
     
    Ivan Vecerina, Nov 2, 2004
    #4
  5. lallous

    Siemel Naran Guest

    "lallous" <> wrote in message
    news:...

    > I noticed that when I use #define inside a namespace then this #define

    only
    > works when prefixed with the namespace name.
    >
    > Is this behaviour standard or just compiler specific?


    Compiler specific. #define is a pre-processor thing, and knows nothing
    about namespaces. Maybe they have a switch to turn off this behavior?
    Check on a microsoft newsgroup (several on msdn.microsoft.com).
     
    Siemel Naran, Nov 2, 2004
    #5
  6. lallous

    JKop Guest

    lallous posted:

    > Hello
    >
    > I noticed that when I use #define inside a namespace then this #define
    > only works when prefixed with the namespace name.



    Really? Please name the compiler, I want to give it a standing ovation.


    > Is this behaviour standard or just compiler specific?
    >
    > I use VC7.
    >
    > namespace test
    > {
    > #define X int
    > };
    >
    > Now can be used as:
    >
    > test::X



    It can also be used as simply:


    X


    which is one reason why you can't do:

    namespace Win
    {
    #include <windows.h>
    }


    -JKop
     
    JKop, Nov 2, 2004
    #6
  7. lallous

    lallous Guest

    > Hello
    >
    > I noticed that when I use #define inside a namespace then this #define
    > only works when prefixed with the namespace name.
    >
    > Is this behaviour standard or just compiler specific?
    >
    > I use VC7.
    >
    > namespace test
    > {
    > #define X int
    > };
    >
    > Now can be used as:
    >
    > test::X
    >


    Thank you all for your replies.

    For those who replied:
    >> Now can be used as:
    >>
    >> test::X

    > It can also be used as simply: X


    That's what I suspected w/o trying the code, but after testing it, it didn't
    work.
    I had to specify which namespace that #define belongs to.

    The code I ran into isn't mine and seeing a #define inside a namespace made
    me pose this question to the newsgroup.

    For those who have VC7, please try this code:

    #include <string>

    namespace std
    {
    #ifdef UNICODE
    //typedef string stringT;
    #define stringT wstring
    #else
    //typedef wstring stringT;
    #define stringT string
    #endif
    }

    int main()
    {
    // works:
    std::stringT test;

    // doesn't work (unless you state the namespace) (error C2065)
    stringT test1;

    return 0;
    }

    I believe adding "typedefs" as I commented out is a better solution.

    --
    Elias
     
    lallous, Nov 2, 2004
    #7
  8. "lallous" <> wrote in message
    news:...
    > > Hello
    > >
    > > I noticed that when I use #define inside a namespace then this #define
    > > only works when prefixed with the namespace name.
    > >
    > > Is this behaviour standard or just compiler specific?
    > >
    > > I use VC7.
    > >
    > > namespace test
    > > {
    > > #define X int
    > > };
    > >
    > > Now can be used as:
    > >
    > > test::X
    > >

    >
    > Thank you all for your replies.
    >
    > For those who replied:
    > >> Now can be used as:
    > >>
    > >> test::X

    > > It can also be used as simply: X

    >
    > That's what I suspected w/o trying the code, but after testing it, it

    didn't
    > work.
    > I had to specify which namespace that #define belongs to.
    >
    > The code I ran into isn't mine and seeing a #define inside a namespace

    made
    > me pose this question to the newsgroup.
    >
    > For those who have VC7, please try this code:
    >
    > #include <string>
    >
    > namespace std
    > {
    > #ifdef UNICODE
    > //typedef string stringT;
    > #define stringT wstring
    > #else
    > //typedef wstring stringT;
    > #define stringT string
    > #endif
    > }
    >
    > int main()
    > {
    > // works:
    > std::stringT test;
    >
    > // doesn't work (unless you state the namespace) (error C2065)
    > stringT test1;
    >
    > return 0;
    > }


    Of course it doesn't work. This is completely standard behaviour. You are
    misunderstanding what is happening. It is because the macro is working that
    you get an error, not because it isn't. Macros pay no attention to
    namespaces at all.

    In the code that doesn't work the macro stringT expands to string, so the
    line of code looks like this

    string test1;

    In the code that does work the macro stringT expands to string, so the line
    of code looks like this

    std::string test;

    The case that doesn't work is an error because string is not qualified with
    a namespace, macros have nothing to do with it. In /both/ cases the macro
    worked and expanded to exactly the same result.

    Undoubtedly typedefs are the correct way to do it, but adding typedefs to
    the std namespace is not legal, even if VC accepts it. Here is how you
    should do it

    #include <string>

    #ifdef UNICODE
    typedef std::string stringT;
    #else
    typedef std::wstring stringT;
    #endif

    or you could even do it like this (VC++ specific code)

    #include <string>
    #include <tchar.h>

    typedef std::basic_string<_TCHAR> stringT;

    john
     
    John Harrison, Nov 2, 2004
    #8
  9. lallous

    lallous Guest

    Hello John,

    >> #include <string>
    >>
    >> namespace std
    >> {
    >> #ifdef UNICODE
    >> //typedef string stringT;
    >> #define stringT wstring
    >> #else
    >> //typedef wstring stringT;
    >> #define stringT string
    >> #endif
    >> }
    >>
    >> int main()
    >> {
    >> // works:
    >> std::stringT test;
    >>
    >> // doesn't work (unless you state the namespace) (error C2065)
    >> stringT test1;
    >>
    >> return 0;
    >> }

    >
    > Of course it doesn't work. This is completely standard behaviour. You are
    > misunderstanding what is happening. It is because the macro is working
    > that
    > you get an error, not because it isn't. Macros pay no attention to
    > namespaces at all.


    Yes, my fault, I didn't see that till you pointed it out.

    >
    > Undoubtedly typedefs are the correct way to do it, but adding typedefs to
    > the std namespace is not legal.


    Why isn't it legal?

    Syntax wise or coding standards wise?

    >even if VC accepts it. Here is how you
    > should do it
    >
    > #include <string>
    >
    > #ifdef UNICODE
    > typedef std::string stringT;
    > #else
    > typedef std::wstring stringT;
    > #endif


    Now that's a typedef solution, but you put "std::" before it? (A)

    I tried to define as:
    int main()
    {
    stringT test; // <-- it works
    std::stringT test1; // <-- it doesn't since stringT isn't a part of std
    namespace; check (A)
    }

    --
    Elias
     
    lallous, Nov 2, 2004
    #9
  10. lallous

    lallous Guest

    Please discard my questions...I must haven't got enough sleep yesterday.

    --
    Elias
     
    lallous, Nov 2, 2004
    #10
  11. > >
    > > Undoubtedly typedefs are the correct way to do it, but adding typedefs

    to
    > > the std namespace is not legal.

    >
    > Why isn't it legal?


    Short answer, because the standard say so.

    Long answer, I would guess, is to give implementors the latitude to
    implement the std namespace in a way that wouldn't work if you tried to add
    new names to it.

    The only thing you are allowed to do is specialise templates that already
    exist in the standard namespace. So this would be legal

    class SpecialChar
    {
    ...
    };

    namespace std
    {
    template <class Tr, class Al>
    class string<::SpecialChar, Tr, Al>
    {
    ...
    };
    }

    Here you are defining your own version of std::string that uses SpecialChar.
    But adding new names is a no-no. This does cause problems sometimes.

    john
     
    John Harrison, Nov 2, 2004
    #11
    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. JustSomeGuy

    How do I define my own namespace?

    JustSomeGuy, Jul 7, 2004, in forum: C++
    Replies:
    1
    Views:
    588
    Mike Wahler
    Jul 7, 2004
  2. theotyflos
    Replies:
    3
    Views:
    474
    Thomas Matthews
    Feb 19, 2004
  3. robin liu
    Replies:
    3
    Views:
    824
    Robin Liu
    Apr 21, 2006
  4. Peng Yu
    Replies:
    0
    Views:
    644
    Peng Yu
    Sep 14, 2008
  5. Brian Takita

    #define _ and #define __

    Brian Takita, Jan 23, 2006, in forum: Ruby
    Replies:
    0
    Views:
    466
    Brian Takita
    Jan 23, 2006
Loading...

Share This Page