Is 'using namespace std;' valid without 'namespace std {};' first?

Discussion in 'C++' started by Petter Reinholdtsen, Nov 23, 2004.

  1. I ran into a problem on HP-UX 11.00 the other day, where it refused to
    compile a program using 'using namespace std;' at the top. The reason
    seem to be that the compiler refuses to accept 'using namespace std;'
    unless the std namespace was declared first.

    This triggered my curiosity, and I tried to find out what the ANSI C++
    standard had to say about this. I'm unable to find a conclusion, and
    hope someone here have a clue to spare.

    Is this code legal ANSI C++, if it is in a file on its own?

    using namespace std;

    It compiles when using GCC, but now when using "aCC: HP aC++/ANSI C
    B3910B A.05.50 [May 15 2003]". The HP-UX compiler protests with "Only
    namespace names are valid here."

    This code compiles without problems, so I concluded that it was the
    lack of a namespace declaration that triggered the bug:

    namespace std {};
    using namespace std;

    Which compiler got this one right? GCC or HP-UX aC++?
     
    Petter Reinholdtsen, Nov 23, 2004
    #1
    1. Advertising

  2. Petter Reinholdtsen wrote in news: in
    comp.lang.c++:

    >
    > I ran into a problem on HP-UX 11.00 the other day, where it refused to
    > compile a program using 'using namespace std;' at the top. The reason
    > seem to be that the compiler refuses to accept 'using namespace std;'
    > unless the std namespace was declared first.
    >
    > This triggered my curiosity, and I tried to find out what the ANSI C++
    > standard had to say about this. I'm unable to find a conclusion, and
    > hope someone here have a clue to spare.


    7.3 Declarations / Namespaces.

    >
    > Is this code legal ANSI C++, if it is in a file on its own?
    >
    > using namespace std;
    >
    > It compiles when using GCC,


    Its possible that gcc (g++) is automagicly including a file that
    declares namespace std, if so it isn't compiling in Standard conforming
    mode or it has a bug.

    > but now when using "aCC: HP aC++/ANSI C
    > B3910B A.05.50 [May 15 2003]". The HP-UX compiler protests with "Only
    > namespace names are valid here."


    Thats correct see 7.3.4.

    >
    > This code compiles without problems, so I concluded that it was the
    > lack of a namespace declaration that triggered the bug:
    >
    > namespace std {};
    > using namespace std;
    >
    > Which compiler got this one right? GCC or HP-UX aC++?
    >


    The latter.

    BTW don't expect the standard to say the likes off:

    " ... the identifier *must* be an existing namespace-name ... "

    as it doesen't need too, as it is specified in the grammar.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Nov 23, 2004
    #2
    1. Advertising

  3. Petter Reinholdtsen

    Howard Guest

    "Petter Reinholdtsen" <> wrote in message
    news:...
    >
    > I ran into a problem on HP-UX 11.00 the other day, where it refused to
    > compile a program using 'using namespace std;' at the top. The reason
    > seem to be that the compiler refuses to accept 'using namespace std;'
    > unless the std namespace was declared first.
    >
    > This triggered my curiosity, and I tried to find out what the ANSI C++
    > standard had to say about this. I'm unable to find a conclusion, and
    > hope someone here have a clue to spare.
    >
    > Is this code legal ANSI C++, if it is in a file on its own?
    >
    > using namespace std;
    >
    > It compiles when using GCC, but now when using "aCC: HP aC++/ANSI C
    > B3910B A.05.50 [May 15 2003]". The HP-UX compiler protests with "Only
    > namespace names are valid here."
    >
    > This code compiles without problems, so I concluded that it was the
    > lack of a namespace declaration that triggered the bug:
    >
    > namespace std {};
    > using namespace std;
    >
    > Which compiler got this one right? GCC or HP-UX aC++?
    >


    You need to have std declared somewhere before you can use it. But adding
    "namespace std {};" isn't really the answer. If you need to use anything
    from the std namespace, you should first include the header file that
    declares those items in that you need. After that include point, you'll be
    able to safely put your using statement without getting an error.

    For example.

    #include <iostream>
    using namespace std;

    However, you might reconsider using the whole namespace. Why not just the
    items you need, like this:

    #include <iostream>
    using std::cout;
    using std::cin;
    using std::endl;

    That's going to reduce the amount of crap from the std namespace that you
    actually bring into your compiled executable. No sense bringing in
    everything in the namespace if you only need a few things, eh?

    -Howard
     
    Howard, Nov 23, 2004
    #3
  4. Petter Reinholdtsen

    Old Wolf Guest

    Rob Williscroft <> wrote:
    > Petter Reinholdtsen wrote:
    >
    > > Is this code legal ANSI C++, if it is in a file on its own?
    > >
    > > using namespace std;

    >
    > BTW don't expect the standard to say the likes off:
    > " ... the identifier *must* be an existing namespace-name ... "
    > as it doesen't need too, as it is specified in the grammar.


    using-directive:
    using namespace ::(opt) nested-name-specifier(opt) namespace-name ;

    namespace-name:
    original-namespace-name
    namespace-alias

    namespace-alias:
    identifier

    original-namespace-name:
    identifier

    and "std" fits the defintion of "identifier", so it seems to be
    valid according to the grammar.

    AFAICS the relevant section is 3.4.6:
    When looking up a /namespace-name/ in a /using-directive/
    or /namespace-alias-definition/, only namespace names are
    considered.

    If 'std' is not a namespace name at the point of lookup (which
    I presume is the point of the using directive), then the lookup
    must fail (which I again presume means that there should be a
    compiler error).
     
    Old Wolf, Nov 23, 2004
    #4
  5. Old Wolf wrote in news: in
    comp.lang.c++:

    > Rob Williscroft <> wrote:
    >> Petter Reinholdtsen wrote:
    >>
    >> > Is this code legal ANSI C++, if it is in a file on its own?
    >> >
    >> > using namespace std;

    >>
    >> BTW don't expect the standard to say the likes off:
    >> " ... the identifier *must* be an existing namespace-name ... "
    >> as it doesen't need too, as it is specified in the grammar.

    >
    > using-directive:
    > using namespace ::(opt) nested-name-specifier(opt) namespace-name ;
    >
    > namespace-name:
    > original-namespace-name
    > namespace-alias
    >
    > namespace-alias:
    > identifier
    >
    > original-namespace-name:
    > identifier
    >
    > and "std" fits the defintion of "identifier", so it seems to be
    > valid according to the grammar.
    >


    My apologies, I gave the impression that *all* you had to do
    was read the grammar, which is clearly incorrect.

    After reading 7.3.1/1 (the grammar) follow it with /2:

    The identifier in an original-namespace-definition shall not have
    been previously defined in the declarative region in which the
    original-namespace-definition appears. The identifier in an
    original-namespace definition is the name of the namespace.
    Subsequently in that declarative region, it is treated as an
    original-namespace-name.

    So an identifier *isn't* an original-namespace-name until
    it has appeared in an original-namespace-definition.

    The point I was trying (failing) to make was that you need to
    read the grammar, you can't just rely on the normal text.

    The grammar connects namespace-name and original-namespace-name.
    Further reading connects original-namespace-definition and the
    proscription that an original-namespace-name only exists *after*
    the original-namespace-defenition.

    > AFAICS the relevant section is 3.4.6:
    > When looking up a /namespace-name/ in a /using-directive/
    > or /namespace-alias-definition/, only namespace names are
    > considered.


    That is saying other names are not considered:

    #include <iostream>
    namespace A
    {
    namespace B { int x; }
    }

    class B {};
    int B;

    using namespace A;
    using namespace B;

    int main()
    {
    x = 10;
    std::cout << x << " Ok\n";
    }

    (* Note: gcc (g++) doesn't get this right *)

    >
    > If 'std' is not a namespace name at the point of lookup (which
    > I presume is the point of the using directive), then the lookup
    > must fail (which I again presume means that there should be a
    > compiler error).


    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Nov 24, 2004
    #5
  6. Re: Is 'using namespace std;' valid without 'namespace std {};'first?

    [Howard]
    > You need to have std declared somewhere before you can use it. But adding
    > "namespace std {};" isn't really the answer. If you need to use anything
    > from the std namespace, you should first include the header file that
    > declares those items in that you need. After that include point, you'll be
    > able to safely put your using statement without getting an error.


    The problem at hand here, is how to write code in a way that work on
    both ANSI C++ compliant compilers, and older slightly broken
    compilers. On HP-UX 11.00, the compiler seem to understand
    namespaces, but the header files do not use the std namespace. So it
    does not help to include the system headers. On all the other
    archs/compilers, the header files declare the std namespace, but the
    code need to compile in both situations.

    Your examples assume only confirming implementations, while I need to
    find a ANSI C++ compliant way to write the code which work on broken
    and correct architectures.

    (If GNU C++ is wrong in this regard, it should be changed to follow
    the standard, but it will take years before I see the effect of such
    change. :)
     
    Petter Reinholdtsen, Nov 24, 2004
    #6
  7. Petter Reinholdtsen

    Howard Guest

    "Petter Reinholdtsen" <> wrote in message
    news:...
    >
    > [Howard]
    >> You need to have std declared somewhere before you can use it. But
    >> adding
    >> "namespace std {};" isn't really the answer. If you need to use anything
    >> from the std namespace, you should first include the header file that
    >> declares those items in that you need. After that include point, you'll
    >> be
    >> able to safely put your using statement without getting an error.

    >
    > The problem at hand here, is how to write code in a way that work on
    > both ANSI C++ compliant compilers, and older slightly broken
    > compilers. On HP-UX 11.00, the compiler seem to understand
    > namespaces, but the header files do not use the std namespace. So it
    > does not help to include the system headers. On all the other
    > archs/compilers, the header files declare the std namespace, but the
    > code need to compile in both situations.
    >
    > Your examples assume only confirming implementations, while I need to
    > find a ANSI C++ compliant way to write the code which work on broken
    > and correct architectures.
    >
    > (If GNU C++ is wrong in this regard, it should be changed to follow
    > the standard, but it will take years before I see the effect of such
    > change. :)


    I'm confused. How can the compiler "understand" namespaces if such
    namespaces are not declared anywhere? There must be some setting for the
    compiler or some included file somewhere that causes the std namespace to be
    included. Or maybe there's a pre-compiled header being used.

    What happens if you do something like this:

    #include <iostream>
    using std::cout;
    using std::cin;
    using std::endl;

    ?

    If that fails on the std:: namespace qualifier, but the include of
    <iostream> works (no warnings or errors), then I'd suspect your system path
    settings or compler options. Maybe you're using the wrong system files or
    something. (I'm not familiar with either compiler, so I can't suggest
    specifics.)

    In any case, you should always use the correct method, which is to include
    the required headers before using any namespace(s) from them. If the
    correct method fails, then ask in a newsgroup devoted to the failing
    compiler, or ask the vendor. Or, don't use the broken compiler.

    -Howard
     
    Howard, Nov 24, 2004
    #7
  8. Re: Is 'using namespace std;' valid without 'namespace std {};'first?

    [Howard]
    > What happens if you do something like this:
    >
    > #include <iostream>
    > using std::cout;
    > using std::cin;
    > using std::endl;
    >
    > ?


    hp-ux 11.00# aCC -c x.c
    Error 112: "x.c", line 1 # Include file <iostream> not found.
    #include <iostream>
    ^^^^^^^^^^
    Error 19: "x.c", line 2 # Unexpected 'std'.
    using std::cout;
    ^^^
    Error 484: "x.c", line 2 # Global object '::cout' not found.
    using std::cout;
    ^^^^
    Error 19: "x.c", line 3 # Unexpected 'std'.
    using std::cin;
    ^^^
    Error 484: "x.c", line 3 # Global object '::cin' not found.
    using std::cin;
    ^^^
    Error 19: "x.c", line 4 # Unexpected 'std'.
    using std::endl;
    ^^^
    Error 484: "x.c", line 4 # Global object '::endl' not found.
    using std::endl;
    ^^^^
    hp-ux 11.00#

    I'm pretty sure that the problem is that the headers lack the std
    namespace specifier by default. Recently I've been told that adding
    -AA helps, and it does.

    > Or, don't use the broken compiler.


    When trying to write code compilable on both broken and conforming
    compilers, I need to stay away from some features, and use some
    features in a special way. The hard part is to find out which
    features to stay away from, and which to use in a special way. :)

    Thank you all of you for explaining why aCC got it right, and GNU C++
    got it wrong, and giving me a few clues on how to write my code to
    make it portable across all the compiler/arch combinations I need to
    use. :)
     
    Petter Reinholdtsen, Nov 25, 2004
    #8
  9. Petter Reinholdtsen

    Old Wolf Guest

    Rob Williscroft <> wrote:
    > Old Wolf wrote:
    > >> Petter Reinholdtsen wrote:
    > >>
    > >> > Is this code legal ANSI C++, if it is in a file on its own?
    > >> > using namespace std;

    > >
    > > original-namespace-name:
    > > identifier
    > >
    > > and "std" fits the defintion of "identifier", so it seems to be
    > > valid according to the grammar.

    >
    > After reading 7.3.1/1 (the grammar) follow it with /2:
    >
    > The identifier in an original-namespace-definition shall not have
    > been previously defined in the declarative region in which the
    > original-namespace-definition appears. The identifier in an
    > original-namespace definition is the name of the namespace.
    > Subsequently in that declarative region, it is treated as an
    > original-namespace-name.
    >
    > So an identifier *isn't* an original-namespace-name until
    > it has appeared in an original-namespace-definition.


    Right, I'm with you now. I guess this is what they mean when
    they say non-context-free grammar.
     
    Old Wolf, Nov 25, 2004
    #9
  10. Petter Reinholdtsen

    Howard Guest

    "Petter Reinholdtsen" <> wrote in message
    news:...
    >
    > [Howard]
    >> What happens if you do something like this:
    >>
    >> #include <iostream>
    >> using std::cout;
    >> using std::cin;
    >> using std::endl;
    >>
    >> ?

    >
    > hp-ux 11.00# aCC -c x.c
    > Error 112: "x.c", line 1 # Include file <iostream> not found.
    > #include <iostream>
    > ^^^^^^^^^^
    > Error 19: "x.c", line 2 # Unexpected 'std'.
    > using std::cout;
    > ^^^
    > Error 484: "x.c", line 2 # Global object '::cout' not found.
    > using std::cout;
    > ^^^^
    > Error 19: "x.c", line 3 # Unexpected 'std'.
    > using std::cin;
    > ^^^
    > Error 484: "x.c", line 3 # Global object '::cin' not found.
    > using std::cin;
    > ^^^
    > Error 19: "x.c", line 4 # Unexpected 'std'.
    > using std::endl;
    > ^^^
    > Error 484: "x.c", line 4 # Global object '::endl' not found.
    > using std::endl;
    > ^^^^
    > hp-ux 11.00#
    >
    > I'm pretty sure that the problem is that the headers lack the std
    > namespace specifier by default.


    In this case, the problem is that the header file is never getting included.
    (Thus, none of those symbols, including std, are defined.) That could be
    due to an old implementation, wrong compiler switches, or missing path. You
    could try #include <iostream.h> and see if that works.

    > Recently I've been told that adding
    > -AA helps, and it does.
    >


    Ok, that's good. I'm not at all familiar with those complers ot their
    switches, personally.
     
    Howard, Nov 29, 2004
    #10
    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. Replies:
    7
    Views:
    443
    Jacek Dziedzic
    Oct 3, 2006
  2. Jeffrey Walton
    Replies:
    10
    Views:
    966
    Mathias Gaunard
    Nov 26, 2006
  3. bb
    Replies:
    1
    Views:
    315
    Alf P. Steinbach
    Sep 7, 2007
  4. Replies:
    2
    Views:
    472
    Werner
    Oct 24, 2012
  5. Shriramana Sharma
    Replies:
    2
    Views:
    159
    Shriramana Sharma
    Jun 27, 2013
Loading...

Share This Page