Thread: global integral constants

  1. #16
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    > It will compile and link correctly, but different compilation units will get different results if they take the address of the constant.

    Well... I'm assuming there is no need to take the address of an integral constant.
    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.

  2. #17
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Well... I'm assuming there is no need to take the address of an integral constant.

    From the first post:
    >> I don't like the "enum-hack" (for one thing, you can't take the address of it if you need to).

    In addition, and someone else can correct me if I'm wrong, but wouldn't a different address mean that the ODR is violated?

  3. #18
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    If you use an unnamed namespace there will be multiple definitions of the constant in the program. It will compile and link correctly, but different compilation units will get different results if they take the address of the constant. I was under the impression that this is what was trying to be avoided.
    That would happen with the original code, with a static variable, would it not?
    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.

  4. #19
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> That would happen with the original code, with a static variable, would it not?
    Yes. Which is what I said earlier.

  5. #20
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    But... who talked about taking the address of the variable? And... what if he does? Wouldn't the address be in scope of whatever unit it was using? If I pass a pointer to a function I'm passing it an address that the function will place in its own scope.

    ... I really don't see the problem here.
    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.

  6. #21
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> But... who talked about taking the address of the variable?
    ChaosEngine said (and I already quoted) that the enum-hack was out because you cannot take the address of an enum.

    Separately, the different addresses are an indication that different constants are created for each compilation unit. Is this a violation of ODR? Isn't that what the question is all about? Your mention of scope is irrelevent. We're not worried about whether the code will compile and link.

  7. #22
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Here is my test code:

    Code:
    // Header.h
    
    #ifndef HEADER_H
    #define HEADER_H
    
    #define USE_UNNAMED_NAMESPACE 1
    
    namespace NS
    {
    #if USE_UNNAMED_NAMESPACE
        namespace
        {
            const int size = 10;
        }
    #else
        enum { size_enum = 10 };
        extern int size;
    #endif
    }
    
    void Test1();
    void Test2();
    
    #endif // HEADER_H
    Code:
    // Source1.cpp
    
    #include <iostream>
    #include "Header.h"
    
    void Test1()
    {
        std::cout << "Test1: " << NS::size << ", " << &(NS::size) << '\n';
    }
    Code:
    // Source2.cpp
    
    #include <iostream>
    #include "Header.h"
    
    void Test2()
    {
        std::cout << "Test2: " << NS::size << ", " << &(NS::size) << '\n';
    }
    Code:
    // main.cpp
    
    #include "Header.h"
    
    #if !USE_UNNAMED_NAMESPACE
    int NS::size = NS::size_enum;
    #endif
    
    int main()
    {
        Test1();
        Test2();
    }
    Change USE_UNNAMED_NAMESPACE to 0 to see it with the enum/extern hack.

  8. #23
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    So those are the only two options if you want to be able to take the address of the variable, right? [edit] Or the static keyword, which does the same thing. [/edit]
    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. #24
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I don't know if that's the only way. You could also make it a member of a class:
    Code:
    struct NS
    {
        static const int size = 10;
    };
    This would mean that all compilations would get the same address for the constant, it would be available for sizing of arrays, and it wouldn't require two different names (like the enum-extern hack). I'm not sure if it is standard, though, to allow the initialization of the static const like that. There might also be other issues I haven't thought of or mentioned.

  10. #25
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    >> I'm not sure if it is standard, though, to allow the initialization of the static const like that.

    from the standard:

    9.4.2.4 If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions.
    so you're sweet.
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  11. #26
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Well I stand corrected and I have learned something new.
    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. basic question about global variables
    By radeberger in forum C++ Programming
    Replies: 0
    Last Post: 04-06-2009, 12:54 AM
  2. Best way to avoid using global variables
    By Canadian0469 in forum C++ Programming
    Replies: 7
    Last Post: 12-18-2008, 12:02 PM
  3. Global objects and exceptions
    By drrngrvy in forum C++ Programming
    Replies: 1
    Last Post: 09-29-2006, 07:37 AM
  4. Initalizing global variables to constants
    By maxhavoc in forum C Programming
    Replies: 6
    Last Post: 06-21-2006, 11:25 AM
  5. defining and using a global class
    By cjschw in forum C++ Programming
    Replies: 4
    Last Post: 03-05-2004, 09:51 PM