Thread: A weird problem of namespace

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    284

    A weird problem of namespace

    A program main.cc:

    Code:
    #include <iostream>                                                             
    #include <string>                                                               
                                                                                    
    namespace Test{                                                                 
    #define STAR "*"                                                                
    }                                                                               
                                                                                    
                                                                                    
    int main(){                                                                     
        std::string str = "this is a test";                                         
        std::string star = "*";                                              
        //std::string star = Test::STAR;                                              
        std::cout<<str<<star<<std::endl;                                          
        return 0;                                                                   
    }
    It works well. But when I replace
    Code:
    std::string star = "*";
    with
    Code:
    std::string star = Test::STAR;
    it reports wierd errors like:
    main.cc:13: error: `std' undeclared (first use this function)

    I suspect it is a problem of namespace. Anybody has a clue?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    #define defines a constant that does not obey the rules of scope since it is a macro.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    The pre-processor runs before the code is compiled, so it knows nothing about namespaces.
    Use a static const char* instead.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Why static? I'd just use a const char* or std::string.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Daved View Post
    Why static? I'd just use a const char* or std::string.
    Doesn't static make global variables local to just one module?

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, it does.
    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
    Jan 2005
    Posts
    7,366
    >> Doesn't static make global variables local to just one module?
    Then why would they be in a named namespace in the first place? In general, use of static for the purpose of making the variable local to one module has been deprecated.

    I don't know whether or how it works to use an unnamed namespace (the preferred alternative) for that purpose with a named namespace as was used in the example.

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Making variables static to restrict them to a file is deprecated in C++, in favour of anonymous namespaces (yes, they do work):
    Code:
    static const char *greet = "Hello, World!";  /* in C */
    namespace {
        const char *greet = "Hello, World!";  // C++
    };
    See also:
    http://www.glenmccl.com/ns_comp.htm (search for "static")
    http://www.informit.com/guides/conte...lus&seqNum=210 (the NOTE at the bottom)
    From that last link, it looks like this was the reasoning:
    Readers have asked me several times why the C++ standards committee frowned at namespace scope static declarations. The first problem was didactic. The keyword static was already overloaded in C; C++ added to this confusion the concept of static data members and static member functions. The committee felt that static was becoming a Swiss army knife: a single keyword that does too many different things.

    Another problem was more subtle. Not all implementations truly support internal linkage. Therefore, the "internal-linkage" promise couldn't be fulfilled in certain environments; hackers familiar with the inner-workings of such implementations could access allegedly-invisible functions and data declared in other translation units. An unnamed namespace, of course, doesn't cure broken linkers; however, it is more honest about its capabilities.

    Article 7.3.1.1/1 of the C++ standard says: "[a]lthough entities in an unnamed namespace might have external linkage, they are effectively qualified by a name unique to their translation unit and therefore can never be seen from any other translation unit." Put differently, an unnamed namespace restricts the visibility of its members to the scope of the translation unit by means of name mangling; it doesn't necessarily guarantee internal linkage, though.
    For more information, check out that page and others. http://www.google.ca/search?hl=en&q=...amespace&meta=
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> (yes, they do work):
    The question is whether they work within a named namespace. Can you make Test::STAR local to the current compilation unit?

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Er, sorry . . . good question. I wonder if this would work? Dinkumware seems to think so, but I can't test multiple files with it, unfortunately.
    Code:
    namespace {
        namespace Test {
            const char *STAR = "*";
        }
    }
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  11. #11
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by dwks View Post
    Code:
    namespace {
        namespace Test {
            const char *STAR = "*";
        }
    }

    You should probably want to do it the other way around, though.

    Code:
    namespace Test {
        namespace  {
            const char *STAR = "*";
        }
    }
    This way you can guarantee the namespace Test carries over other compilation units, whereas the name Test::STAR is local to this unit.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Weird problem with sscanf
    By g4j31a5 in forum C++ Programming
    Replies: 17
    Last Post: 10-04-2006, 09:16 PM
  2. weird problem!
    By spank in forum C Programming
    Replies: 2
    Last Post: 04-08-2006, 03:26 AM
  3. very weird .h problem
    By royuco77 in forum C++ Programming
    Replies: 1
    Last Post: 09-11-2005, 07:55 AM
  4. Replies: 6
    Last Post: 05-12-2005, 03:39 AM
  5. Weird class problem!
    By aker_y3k in forum C++ Programming
    Replies: 2
    Last Post: 09-25-2002, 06:12 AM