namespace and #define

L

lallous

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
 
S

Sharad Kala

lallous said:
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
 
I

Ivan Vecerina

lallous said:
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
 
S

Siemel Naran

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).
 
J

JKop

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
 
L

lallous

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:
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.
 
J

John Harrison

lallous said:
Thank you all for your replies.

For those who replied:

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
 
L

lallous

Hello John,
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)
}
 
J

John Harrison

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
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top