Thread: extern const?Please help

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

    extern const?Please help

    Hi guys,

    I am kinda confused with extern const and const.
    Please help to explain the usage of both.
    I am having compilation/linking error when using extern const and const.

    The code are written in c but I am using c++ compiler as the project contains both c and c++ codes.

    In svc_tone.h
    Code:
    /* Function prototype */
    void svcRequestTone(int, int *);
    ....
    In test.c
    Code:
    #include "svc_tone.h"
    ....
    const int tone_table[] ={1, 2, 3};
    In test_user_defs.h
    Code:
    #include "svc_tone.h"
    ....
    /* Basic Data Types */
    extern const int tone_table[];
    In test.h
    Code:
    #include "test_user_defs.h"
    ....
    ....
    /* Function prototype */
    void functionABC(int TaskID);
    ...
    ....
    In test_function.c
    Code:
    #include "test.h"
    ....
    ....
    ...
    ...
    void functionABC(int TaskID)
    {
         svcRequestTone(TaskID, tone_table); // line 200
    }
    When I compiled it, the error I got in test_function.c, at line 200:-
    "argument of type "const int *" is incompatible with parameter of type "int *" tone_table "

    I tried putting a "const" at the function "svcRequestTone" argument list, hence the function is now becomes:-
    In svc_tone.h
    Code:
    /* Function prototype */
    void svcRequestTone(int, const int *);
    ....
    and it works...this managed to solve the error!!

    I just wonder why the "const" keyword is required??Can anyone please tell me?


    Next, after solving the above compilation error, I had a linking error that says undefined symbol for "tone_table".

    In order to solve it, I modified the test.c by adding "extern" keyword to the declaration.
    In test.c
    Code:
    #include "svc_tone.h"
    ....
    extern const int tone_table[] ={1, 2, 3};
    And guess what, it builds sucessfully!!

    Can anyone tell me, would it cause any problems by adding the "extern" to its declarartion?
    Why is it an "extern const" is needed in the declaration instead of just the "const"?
    (why both .c and .h need to be "extern const"?).

    Please help!!
    Thanks guys!!!!

  2. #2
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    I just wonder why the "const" keyword is required??Can anyone please tell me?
    const is required because there's no implicit conversion from const int * to int *. int * mean that you can modify the element to which the pointer points. const int * mean that you can't modify the element to which the pointer points. Your array is defined as being an array of const elements, so you can't modify the element the array holds; if you can't, the functions using the array can't either.

    Can anyone tell me, would it cause any problems by adding the "extern" to its declarartion?
    Why is it an "extern const" is needed in the declaration instead of just the "const"?
    It won't cause any problem to add "extern" to the definition. In fact, you want the extern keyword to be there. And you certainly want the extern keyword to show in every declaration. In C++, const global variables are static by default (contrary to C, where they are extern by default). By defining a variable as extern, you make it available to other source files.

    This can be a bit confusing. If you look on google for extern/static keywords, you might find something enlightening.
    Last edited by foxman; 07-22-2008 at 09:36 AM.
    I hate real numbers.

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    30
    Thanks a lot Foxman!!

    But when I built it with C compiler, there was no such error when I didn't put "const".
    Is this also one of the differences btw C and C++?

  4. #4
    Registered User
    Join Date
    Apr 2007
    Posts
    30
    If we declare a constant array with "const" like below,

    In abc.c
    Code:
    ....
    const int tone_table[] ={1, 2, 3};
    in header_def.h
    Code:
    ....
    extern int tone_table[];
    Can we define tone_table in header_def.h with just the "extern" keyword instead of like this:
    extern const int tone_table[];

    Is there any difference with and without "const" when we have declared it as constant array in the source file?
    Please help.
    Thanks

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Const is used to tell the compiler that the this variable will not/cannot be modified. There is a difference between "const T" and "T", because the compiler treats them as different types.
    The "extern" keyword is used to typically tell the compiler that a variable is indeed defined, but not within the current source file (or compilation unit). To help the compiler (and the linker!), you must put the EXACT same type.

    Example 1:
    const int myint = 5;
    extern const int myint;
    extern int myint; // Will cause a linking error

    Example 2:
    int myint = 5;
    extern int myint; // OK
    extern const int myint; // Will cause a linking error

    Also, do not put globals inside headers, because the compiler will happily include the same global in multiple source files, but when the linker encounters them, it will give an error.
    With normal constant, simple values, such as const int, it's OK to define them in a header because the compiler will treat them as constant expressions. That means it will basically just replace the variable name with the variable contents wherever it encounters it. The variable will actually never be created. I don't know if this applies to arrays, however.
    Last edited by Elysia; 08-05-2008 at 06:08 AM.
    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.

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    In C++, constant global variables are automatically static; that is, they are restricted to the scope of the file in which they are declared. This means that you can declare a constant variable of the same name in multiple source files, and it will compile.

    (In C, it's a little different.)

    None of this applies to non-constant global variables in C++, unless you explicitly make them static, too. (But that might not do what you want, because such variables behave differently.)

    It's worth noting that you can do this:
    Code:
    extern int x;
    int x = 3;
    In fact, you can precede a declaration with any number of identical (except for initialization) extern declarations.

    This means that you can do this in a header file
    Code:
    extern int x;
    and then in one source file, actually declare the variable:
    Code:
    int x = 4;  // initialization optional
    You can then include that header file in any source file that needs to use the global variable, even the source file that actually declares the global variable.
    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.

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    30
    Here is another question.

    In test.c
    Code:
    extern const int try_table[] = {1, 2, 3};
    In test_user_def.h
    Code:
    extern int try_table[];   // Note that this array is defined without "const" keyword
    In try_source.c
    Code:
    ...
    #include "test_user_def.h"
    ...
    ...
    
    void function_test()
    {
       ....
       ....
       testTry_table(try_table);
       ....
    }
    The above code were compiled successfully.

    I just wonder why the compilation was sucessful when try_table[] was defined without the "const" keyword.
    For some of other const global variables, if the variables were defined without "const", the compiler complains with "declaration is incompatible....".
    Last edited by huwan; 08-12-2008 at 02:46 AM.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You should have const in both places. Also, I would expect that if you include test_user_def.h into your test.c file, the compiler will complain about inconsistent const-ness.

    Unfortunately, the linker [particularly in C, as opposed to C++] symbols do not contain information about type. For example, we can do this:
    Code:
    // foo.c
    #include <stdio.h>
    int foo()
    {
        printf("Hello, world\n");
    }
    
    // main.c
    #include <stdio.h>
    int main()
    {
        extern int foo[];
        printf("foo[0] = &#37;d\n", foo[0]);
        return 0;
    }
    This won't make much sense, but the compiler WILL allow it.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Apr 2007
    Posts
    30
    Yeah! You are right!
    I just realised test.c did not include test_user_def.h, that's why there was no error.

    But for other const global variables declaration files, they included the header file therefore the compiler found the mismatch.

    So, for the variable declaration consistency, should I add the "const" to
    extern const int try_table[]; // in test_user_def.h

    or just leave it without the "const"?
    Would it matter if I add the "const" to it?

  10. #10
    Registered User
    Join Date
    Apr 2007
    Posts
    30
    When we do constant global variable assignment, is it a must to always assign it to a variable which is also a constant?

    For eg:

    In const_header.h
    Code:
    extern const int volume_arr[] ;
    extern int *volume_pointer ;
    In const.c
    Code:
    #include "const_header.h"
    ....
    
    const int volume_arr[] = { 2, 3, 4, 5};
    .....
    .....
    
    int *volume_pointer = volume_arr;  // line 1....

    I had a compilation error at line 1 but I can't remember the error message.

    In order to solve it, I changed:-

    In const.c
    Code:
    const int *volume_pointer = volume_arr;
    In const_header.h
    Code:
    extern const int volume_arr[] ;
    extern const int *volume_pointer ;
    This changes solved the error.
    Is this correct way to solve it?
    Please help.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The const keyword is used to tell the compiler that "I'm not going to change this". The compiler will then use that information for two purposes:
    1. Validating that you are not breaking your own rule of not changing it.
    2. Optimize code that uses that constant data by knowing that it doesn't change (for example, a const variable is not expected to change across a function call, so if it is held in a local register, the compiler won't have to re-load it after the function call).

    Naturally, if you "loose" the const-ness, then you are breaking your own rules, because after you have lost the const, the data is possibly going to change. It is harmless to "add" const to something, it doesn't change what the compilers assumptions are.

    So whenever something starts out as const, it should be kept as const. If you have something that wasn't const from the beginning, you can make it const. But you can't "unconst" something. If you REALLY know what you are doing [and you should check at least twice that you are SURE that you know what you are doing], then you can use a cast to remove const [in C++ there is a special const_cast<T>(expr) form] - but it's NASTY and usually incorrect to "loose" the const.

    As a summary, you should never REMOVE const. You should never assign the address of something const to a non-const pointer. Never pass a const pointer to a non-const parameter of a function.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. extern classes
    By Swordsman in forum C++ Programming
    Replies: 1
    Last Post: 05-07-2008, 02:07 AM
  2. Replies: 16
    Last Post: 10-29-2006, 05:04 AM
  3. Odd Problem with Linking
    By jamez05 in forum C++ Programming
    Replies: 6
    Last Post: 09-21-2005, 01:49 PM
  4. Extern Question, really confused
    By SourceCode in forum C Programming
    Replies: 10
    Last Post: 03-26-2003, 11:11 PM
  5. extern symbols, what do these mean exactly?
    By Shadow12345 in forum C++ Programming
    Replies: 8
    Last Post: 11-02-2002, 03:14 PM