Thread: "extern const int" creates linking errors that "extern int" doesn't

  1. #1
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131

    "extern const int" creates linking errors that "extern int" doesn't

    Hello.

    2 source files main.cpp def.cpp
    main.cpp:
    Code:
    #include <iostream>
    using namespace std;
    
    extern const int a;
    
    int main()
    {
        cout << a << endl;
    }
    def.cpp:

    Code:
    const int a = 4;

    when I compile it like this:
    g++ main.cpp def.cpp -c
    g++ main.o def.o

    I get this error:
    main.o(.text+0x12b):main.cpp: undefined reference to `a'
    collect2: ld returned 1 exit status

    But when I remove the "const" from the extern and from the actual definition of the value, it works. Why is it so and how to avoid id?

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    It looks like you're doing things backwards to me:
    Code:
    // def.h:
    extern const int a;
    
    // new.cpp:
    #include <iostream>
    #include "def.h"
    
    const int a = 42;
    
    int main() {
       std::cout << "a = " << a << std::endl;
       return 0;
    }

  3. #3
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    imho extern is for saying: "this variable is declared elsewhere. Don't worry, compiler, I'll show you the right spot when the time comes".

    thus, in main.cpp i want to use a variable that is defined in another .cpp file.
    I don't want to do it your way, citizen, because if I'd want to use the const int a in another file, what should I do? define it again?

    Imho I should define a variable only once, but I can use it as much as possible, not vice versa.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    Help me, god of C.

  5. #5
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    try put
    const int a = 42;

    in the def.h and remove extern declarations

    In C, constant values default to external linkage, so they can appear only in source files. In C++, constant values default to internal linkage, which allows them to appear in header files.
    Last edited by vart; 12-14-2006 at 01:34 PM.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  6. #6
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    it would work, but it's just ignoring the problem.

    Does anyone know why the "const" wants to mess with me?

  7. #7
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by hardi
    it would work, but it's just ignoring the problem.

    Does anyone know why the "const" wants to mess with me?
    No it means to work according to C++ standard
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  8. #8
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    Quote Originally Posted by vart
    No it means to work according to C++ standard
    what do you mean?

  9. #9
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Just what I have already said
    In C++, constant values default to internal linkage, which allows them to appear in header files.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  10. #10
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    > what should I do?
    Nothing. Just make sure that it's declared:
    Code:
    // def.h
    #ifndef DEF_H_INCLUDED
    #define DEF_H_INCLUDED
    #include <iostream>
       void print();
       extern const int a;
    #endif
    
    // main.cpp
    #include <iostream>
    #include "def.h"
    
    const int a = 42;
    
    int main() {
       std::cout<<"a = " << a << " in main.\n";
       print();
    }
    
    // again.cpp
    #include <iostream>
    #include "def.h"
    
    void print() {
       std::cout << "a = " << a << " in another file.\n";
    }
    You can initialize a wherever you like. It's just that other files are dependant on def.h

  11. #11
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    it will work in C not C++
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  12. #12
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Really?

    Owner@pavilion ~
    $ g++ new.cpp again.cpp -w -Wall -ansi -pedantic

    Someone ought to have told me that I wasn't compiling C++.

    Owner@pavilion ~
    $ ./a
    a = 42 in main.
    a = 42 in another file.

    I suppose I'm magical.

  13. #13
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by citizen
    Really?

    I suppose I'm magical.
    I suppose so
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  14. #14
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    ok, I don't understand it, but actually there is no need to make a def.h containing an "extern" and a .cpp to define that externed variable - I could just put the definition in the .h file, as you recommended me, vart.

  15. #15
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    > ok, I don't understand it
    The whole point of the extern keyword is to extend a variable's lifespan beyond file scope. It allows global constants to exist across an entire project.

    Vart's quote from the standard states that constants are linked internally in C++ by default, allowing you to initialize a constant in a header file. In the language's predecessor, C, constants weren't allowed to be initialized in header files, so extern was used. C++ supports the extern keyword because it was inherited from C. If someone can prove that a constant must or shall be linked internally, then I'll gladly shut up.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Polynomials and ADT's
    By Emeighty in forum C++ Programming
    Replies: 20
    Last Post: 08-19-2008, 08:32 AM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. problem with const int inside class (c2258)
    By talz13 in forum C++ Programming
    Replies: 1
    Last Post: 11-23-2003, 07:34 PM
  4. vector<>
    By teval in forum C++ Programming
    Replies: 11
    Last Post: 08-18-2003, 03:27 PM
  5. errors in class(urgent)
    By ayesha in forum C++ Programming
    Replies: 2
    Last Post: 11-10-2001, 06:51 PM