Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > #include within namespace scope

Reply
Thread Tools

#include within namespace scope

 
 
joecook@gmail.com
Guest
Posts: n/a
 
      02-16-2009
Is there anything that prevents putting #include directives inside
namespace scope within the standard?

Let's say I have a (evil) header:

header.h
#include <vector>
using namespace std; // bad doggy

class Doo
{
public:
vector<int> d;
};
----------
and a test.cc:
namespace evil
{
#include "header.h"
}
int main()
{
// Nothing
}

gcc throws up all over the place. What rule am I violating?

Joe C
 
Reply With Quote
 
 
 
 
Pascal J. Bourguignon
Guest
Posts: n/a
 
      02-16-2009
writes:

> Is there anything that prevents putting #include directives inside
> namespace scope within the standard?


Nothing, but you will declare the stuff defined in the header inside
this namespace.

> Let's say I have a (evil) header:


Therefore you have:


namespace evil
{
#include <vector>
using namespace std; // bad doggy

class Doo
{
public:
vector<int> d;
};
}
int main()
{
// Nothing
}

That is, you are using a class evil::std::vector<int>
Where is the implementation of this class?
Notice that libg++ only defines methods such as std::vector<int>::clear,
not evil::std::vector<int>::clear.

So as long as you defined all the methods and classes you have defined
in evil::std somewhere, and would link them with your program it would
be ok.

--
__Pascal Bourguignon__
 
Reply With Quote
 
 
 
 
Zeppe
Guest
Posts: n/a
 
      02-16-2009
wrote [16/02/09 13:27]:
> Is there anything that prevents putting #include directives inside
> namespace scope within the standard?


I'd be surprised if it weren't.

>
> Let's say I have a (evil) header:
>
> header.h
> #include <vector>


[...]

> and a test.cc:
> namespace evil
> {
> #include "header.h"
> }


[...]

> gcc throws up all over the place. What rule am I violating?


The rule of common sense. The headers include a bounch of declarations
and definitions within the namespace std, you cannot change the
namespace and expect that everything works.

A workaround is to #include <vector> in test.cc or elsewhere before the
inclusion in header.h, so that the standard things stay the same. Sort
of a new wrapper file:

header_wrap.h

#include <vector>
namespace evil{
#include <header.h> // vector won't be included in namespace evil.
}

Best wishes,

Zeppe
 
Reply With Quote
 
joecook@gmail.com
Guest
Posts: n/a
 
      02-16-2009
On Feb 16, 9:10*am, p...@informatimago.com (Pascal J. Bourguignon)
wrote:
> joec...@gmail.com writes:
> > Is there anything that prevents putting #include directives inside
> > namespace scope within the standard?

>
> Nothing, but you will declare the stuff defined in the header inside
> this namespace.
>
> > Let's say I have a (evil) header:

>
> Therefore you have:
>
> * * namespace evil
> * * {
> * * #include <vector>
> * * using namespace std; *// bad doggy
>
> * * class Doo
> * * {
> * * public:
> * * *vector<int> d;
> * * };
> * * }
> * * int main()
> * * {
> * * * // Nothing
> * * }
>
> That is, you are using a class *evil::std::vector<int>
> Where is the implementation of this class?
> Notice that libg++ only defines methods such as std::vector<int>::clear,
> not evil::std::vector<int>::clear.


I expected the preprocessor to expand the include header at the
location I have put it.
I further expected that the compiler should always refer to ::std::
instead of std::, and therefore 'std' will not get caught inside the
namespace where it is not intended. Somewhere that expectation is
being broken, and I'm still not sure exactly where..
Joe C
 
Reply With Quote
 
joecook@gmail.com
Guest
Posts: n/a
 
      02-16-2009
On Feb 16, 10:18*am, joec...@gmail.com wrote:
> On Feb 16, 9:10*am, p...@informatimago.com (Pascal J. Bourguignon)
> wrote:
>
>
>
>
>
> > joec...@gmail.com writes:
> > > Is there anything that prevents putting #include directives inside
> > > namespace scope within the standard?

>
> > Nothing, but you will declare the stuff defined in the header inside
> > this namespace.

>
> > > Let's say I have a (evil) header:

>
> > Therefore you have:

>
> > * * namespace evil
> > * * {
> > * * #include <vector>
> > * * using namespace std; *// bad doggy

>
> > * * class Doo
> > * * {
> > * * public:
> > * * *vector<int> d;
> > * * };
> > * * }
> > * * int main()
> > * * {
> > * * * // Nothing
> > * * }

>
> > That is, you are using a class *evil::std::vector<int>
> > Where is the implementation of this class?
> > Notice that libg++ only defines methods such as std::vector<int>::clear,
> > not evil::std::vector<int>::clear.

>
> I expected the preprocessor to expand the include header at the
> location I have put it.
> I further expected that the compiler should always refer to ::std::
> instead of std::, and therefore 'std' will not get caught inside the
> namespace where it is not intended. *Somewhere that expectation is
> being broken, and I'm still not sure exactly where..
> Joe C- Hide quoted text -
>
> - Show quoted text -


To clarify,

The standard states, "Whenever a name x defined in the standard
library is mentioned, the name x is assumed to be fully qualified
as ::std:, unless explicitly described otherwise. For example, if
the Effects section for library function F is described as calling
library function G, the function ::std::G is meant."

In this case, the compiler seems to be making the assumption that
include directives will always be at global scope, but I cannot find
any part of the standard that would back up such an assumption. That
is what I am searching for.

Thanks!
Joe C
 
Reply With Quote
 
Pascal J. Bourguignon
Guest
Posts: n/a
 
      02-16-2009
writes:
>> I expected the preprocessor to expand the include header at the
>> location I have put it.


That's what it does.

>> I further expected that the compiler should always refer to ::std::
>> instead of std::, and therefore 'std' will not get caught inside the
>> namespace where it is not intended.


They would have to write ::std:: all over the standard headers.

>> Somewhere that expectation is
>> being broken, and I'm still not sure exactly where..

>
> To clarify,
>
> The standard states, "Whenever a name x defined in the standard
> library is mentioned, the name x is assumed to be fully qualified
> as ::std:, unless explicitly described otherwise. For example, if
> the Effects section for library function F is described as calling
> library function G, the function ::std::G is meant."


This seems to me to be a meta-rule about the interpretation of the
text of the standard. It says nothing about the header files.


> In this case, the compiler seems to be making the assumption that
> include directives will always be at global scope, but I cannot find
> any part of the standard that would back up such an assumption. That
> is what I am searching for.


Or to infirm it. It would be nice to find it.

--
__Pascal Bourguignon__
 
Reply With Quote
 
Zeppe
Guest
Posts: n/a
 
      02-16-2009
Victor Bazarov wrote [16/02/09 15:01]:
> Zeppe wrote:
>> wrote [16/02/09 13:27]:
>>> Is there anything that prevents putting #include directives inside
>>> namespace scope within the standard?

>>
>> I'd be surprised if it weren't.

>
> The concept of a namespace has nothing to do with the preprocessor. So,
> those two are orthogonal, and there can be NO provision making the two
> somehow connected. Are you surprised?


In order for the std headers to work, they have to be included outside
of any namespace. Whatever the reason, this is a rule, and I expect it
to appear somewhere in the standard, since, as you said, namespaces and
preprocessor are orthogonal and in principle I could expect to be able
to include standard headers at any point.

But, no, I'm not surprised, because of 17.4.2.1#3:
"A translation unit shall include a header only outside of any external
declaration or definition, and shall include the header lexically before
the first reference to any of the entities it declares or first defines
in that translation unit."

>> The rule of common sense. The headers include a bounch of declarations
>> and definitions within the namespace std,

>
> Actually, more precisely, the namespace ::std.


yes, that is, of course. It was the whole core of the topic

Best wishes,

Zeppe
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-17-2009
On Feb 16, 2:27 pm, joec...@gmail.com wrote:
> Is there anything that prevents putting #include directives
> inside namespace scope within the standard?


Of course not. Include happens before namespaces are
recognized, and is pure textual inclusion. You can put one in
the middle of a function, if that's what you want.
The only restriction in the standard is with regards to the
standard includes; these must be included "outside of any
external declaration or definition." I'm not sure why the
particular exact wording, but namespaces and classes do count as
declarations, so the include of a standard header must be
outside of them.

> Let's say I have a (evil) header:


> header.h
> #include <vector>
> using namespace std; // bad doggy


> class Doo
> {
> public:
> vector<int> d;};


> ----------
> and a test.cc:
> namespace evil
> {
> #include "header.h"
> }


> int main()
> {
> // Nothing
> }


> gcc throws up all over the place. What rule am I violating?


You're including a standard header (indirectly) inside a
namespace.

More generally, since headers are textual inclusion, it's very
hard to write one which can really be included within a
namespace. The standard doesn't care, but there's a very large
possibility that the results will not be what you want (unless
the header only contains #define).

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-17-2009
On Feb 16, 4:18 pm, joec...@gmail.com wrote:
> On Feb 16, 9:10 am, p...@informatimago.com (Pascal J. Bourguignon)
> wrote:
> > joec...@gmail.com writes:
> > > Is there anything that prevents putting #include
> > > directives inside namespace scope within the standard?


> > Nothing, but you will declare the stuff defined in the
> > header inside this namespace.


> > > Let's say I have a (evil) header:


> > Therefore you have:


> > namespace evil
> > {
> > #include <vector>
> > using namespace std; // bad doggy


> > class Doo
> > {
> > public:
> > vector<int> d;
> > };
> > }
> > int main()
> > {
> > // Nothing
> > }


> > That is, you are using a class evil::std::vector<int>
> > Where is the implementation of this class?
> > Notice that libg++ only defines methods such as std::vector<int>::clear,
> > not evil::std::vector<int>::clear.


> I expected the preprocessor to expand the include header at
> the location I have put it. I further expected that the
> compiler should always refer to ::std:: instead of std::, and
> therefore 'std' will not get caught inside the namespace where
> it is not intended.


Part of the problem may be that the library is doing just that:
using ::std::, instead of just std::. So <vector> includes
something like:

namespace std
{
namespace _Private_ {
class _UsedByVector { /* ... */ } ;
}
template< ... >
class vector
{
// ...
::std::_Private_::_UsedByVector ...
} ;
}

When you wrap this in namespace evil,
::std::_Private_::_UsedByVector isn't defined, only
::std::_Private_::_UsedByVector.

It's because of such things that the standard makes the
requirement that standard headers may not be included in
declarations or definitions.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-17-2009
On Feb 16, 4:47 pm, joec...@gmail.com wrote:
> On Feb 16, 10:18 am, joec...@gmail.com wrote:
> > On Feb 16, 9:10 am, p...@informatimago.com (Pascal J. Bourguignon)
> > wrote:


> > > joec...@gmail.com writes:
> > > > Is there anything that prevents putting #include
> > > > directives inside namespace scope within the standard?


> > > Nothing, but you will declare the stuff defined in the
> > > header inside this namespace.


> > > > Let's say I have a (evil) header:


> > > Therefore you have:


> > > namespace evil
> > > {
> > > #include <vector>
> > > using namespace std; // bad doggy


> > > class Doo
> > > {
> > > public:
> > > vector<int> d;
> > > };
> > > }
> > > int main()
> > > {
> > > // Nothing
> > > }


> > > That is, you are using a class evil::std::vector<int>
> > > Where is the implementation of this class? Notice that
> > > libg++ only defines methods such as
> > > std::vector<int>::clear, not
> > > evil::std::vector<int>::clear.


> > I expected the preprocessor to expand the include header at
> > the location I have put it. I further expected that the
> > compiler should always refer to ::std:: instead of std::,
> > and therefore 'std' will not get caught inside the namespace
> > where it is not intended. Somewhere that expectation is
> > being broken, and I'm still not sure exactly where..


> To clarify,


> The standard states, "Whenever a name x defined in the standard
> library is mentioned, the name x is assumed to be fully qualified
> as ::std:, unless explicitly described otherwise. For example, if
> the Effects section for library function F is described as calling
> library function G, the function ::std::G is meant."


I'm not sure where it says that, so I can't verify the context,
but I imagine that it is talking about the use of names in user
code. That the guarantees concerning e.g. vector only hold if
vector actually refers to ::std::vector (and not for
::std::vector). And of course, you can't define a class:

template< ... >
class ::std::vector ...

(See §3.4.4/3, which specifies look-up after a class specifier
or an enum specifier. Particularly "If the name is a
qualified-id [the case in the above], [...]. If the name lookup
does not find a previously declared class-name or enum-name, the
elaborated-type-specifier is ill formed. In everyday terms:
class ::std::whatever ...
is ill formed unless there is a preceding
namespace std { class whatever; }
somewhere in global namespace.)

> In this case, the compiler seems to be making the assumption
> that include directives will always be at global scope, but I
> cannot find any part of the standard that would back up such
> an assumption.


The "compiler" is making no assumptions what so ever. It is
compiling what it sees, after textual inclusion. You're
violating §17.4.2.1/3 "A translation unit shall include a header
only outside of any external declaration, [...]"

More generally, most people assume that headers will be included
only outside of any external declaration when they write them.
This is almost always a constraint on the use of a header
(non-standard headers as well), and I suspect that it's often
not documented---unless the library documents that you can
include a header in a namespace, class definition or function
definition, I would assume that you couldn't.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Lexical scope vs. dynamic scope Xah Lee Java 0 02-26-2009 10:08 AM
Scope - do I need two identical classes, each with different scope? ann Java 13 09-13-2005 03:07 AM
How do namespace scope and class scope differ? Steven T. Hatton C++ 9 07-19-2005 06:07 PM
IMPORT STATIC; Why is "import static" file scope? Why not class scope? Paul Opal Java 12 10-10-2004 11:01 PM
Namespace: Is it a scope or a namespace? Anonymous C++ 3 08-18-2003 01:31 PM



Advertisments