Thread: namespace problem

  1. #1
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99

    namespace problem

    Another beginner question...

    The following compiles and runs without any problem:

    Code:
    #include <iostream>
    
    using namespace std;
    
    namespace ns1
    {
        char *string1 = "string 1 ns1";
        char *string2 = "string 2 ns1";
    }
    
    namespace ns2
    {
        char *string1 = "string 1 ns2";
        char *string2 = "string 2 ns2";
    }
    
    namespace comb1
    {
        using namespace ns1;
        using namespace ns2;
        using ns1::string1;
        using ns2::string2;
    }
    
    int main()
    {
         cout << comb1::string1 << ", " <<comb1::string2 << endl;
         return 0;
    }
    However, if I change the first line in main() to:

    Code:
    using namespace comb1;
    cout << string1 << ", " << string2 << endl;
    the compiler gets confused by the conflicting definitions of string1 and string2 and gives an error. I can't see why there should be any difference between the two versions.

    Any suggestions?

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Irrelevant to the example, but you should never assign a string literal to a non-const char pointer.

    Name lookup is a very complex matter. Comeau and GCC agree that the symbols are ambiguous, and when those agree, they are usually right. I'd have to look up the exact lookup rules in the standard for the justification though, and I'm too tired to do so now.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    May I ask what the problem is with using a non-const pointer (that rule doesn't apply in C, does it?) if you are careful not to try changing the string?

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    String literals cannot be modified. Assigning those literals to const char * aids the compiler in enforcing this dictum, which is much buffer than a seg-fault down the road when you execute the program. Const correctness is important to both C and C++.

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> if you are careful not to try changing the string?
    It depends on what you mean by careful. If you're 100&#37; sure, then there is no problem. If you're 99% sure, then it doesn't hurt to do it properly and allow the compiler to catch the mistake in that 1% likelihood that you (or the person who works on the code after you) messes up.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    This applies to both C and C++.
    Although in C++, you would rather use std::string instead.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by DL1 View Post
    Another beginner question...

    The following compiles and runs without any problem:

    Code:
    #include <iostream>
    
    using namespace std;
    
    namespace ns1
    {
        char *string1 = "string 1 ns1";
        char *string2 = "string 2 ns1";
    }
    
    namespace ns2
    {
        char *string1 = "string 1 ns2";
        char *string2 = "string 2 ns2";
    }
    
    namespace comb1
    {
        using namespace ns1;
        using namespace ns2;
        using ns1::string1;
        using ns2::string2;
    }
    
    int main()
    {
         cout << comb1::string1 << ", " <<comb1::string2 << endl;
         return 0;
    }
    However, if I change the first line in main() to:

    Code:
    using namespace comb1;
    cout << string1 << ", " << string2 << endl;
    the compiler gets confused by the conflicting definitions of string1 and string2 and gives an error. I can't see why there should be any difference between the two versions.

    Any suggestions?
    I think that when you say:
    Code:
    cout << comb1::string1
    it's looking for a variable in comb1 called string1, and it finds it explicitly declared in you using statement. However, when you don't qualify it with comb1:: it looks at all of the available namespaces, probably in order in which they were declared, so it starts with comb1, finds ns1::string1, and then also sees that ns2 (of which you have included all in your global namespace by saying using namespace ns2) also contains variables string1 and string 2, causing the compiler to become confused about which one you want. I'll bet if you do it the following way:

    Code:
    namespace comb1
    {
        using ns1::string1;
        using ns2::string2;
        using namespace ns1;
        using namespace ns2;
    }
    it will probably compile just fine, although I don't really have the ability to check right at the moment.

  8. #8
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    So you wrote code that has no unambiguous meaning to a human and are asking how come the compiler behaves a certain way. To be honest I am not 100&#37; positive on which the compiler even thinks you are using. So if I were part of your dev team, and you wrote that and I have no idea what it functionally does, what difference does it make whether or not your compiler takes a stab at guessing?

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    OK, so the first version is disambiguated by the first run-on sentence of 3.4.3.2/2. It says that, if the target namespace has the name in question, all namespaces pulled in by using directives are ignored.

    7.3.4 contains examples very closely resembling the second version and declare it invalid due to the ambiguity. Unqualified name lookup, 3.4.1, is a complete mess, and I cannot quite make it out if "name lookup ends as soon as a declaration is found for the name" means that multiple declarations may be found in the same scope or not.
    Nevertheless, 7.3.4/6 apparently disambiguates the intent of 3.4.1.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. extern namespace?
    By Brafil in forum C++ Programming
    Replies: 2
    Last Post: 01-10-2009, 08:06 AM
  2. global namespace errors
    By stubaan in forum C++ Programming
    Replies: 9
    Last Post: 04-02-2008, 03:11 PM
  3. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  4. Problem with atoi()?
    By ruthgrin in forum C++ Programming
    Replies: 4
    Last Post: 03-19-2006, 12:25 PM
  5. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM