Re: #include within namespace scope
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::x, 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
::evil::std::vector). And of course, you can't define a class:
template< ... >
class ::std::vector ...
(See =A73.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 =A717.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:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34