Thread: redefining variables without extern

  1. #1
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129

    redefining variables without extern

    I was perusing C99 (6.9.2.4) and found that at file scope, you can "redefine" variables:
    Code:
    int i;
    int i; //legal
    int i;
    int i;
    int i;
    
    int main()
    {
            int i;
            int i; //illegal
            return 0;
    }
    I was wondering, what is the purpose of this? Why not use extern for the duplicates?

  2. #2
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Probably because extern is assumed for global variables if not specified. The reason to allow duplicates is so that you can include a header that specifies the global variable, then in the source itself define it again with an initial value.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    So if variables are extern by default, what's the point of the extern keyword?

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    For spelling it out.

    I'm not 100% sure that variables are extern by default, though. But even it they're not, having the same parsing rules whether static or extern is used is simpler.

    C is not written to minimize key words. For example the auto key word, used to specify non-static variables, is completely useless.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    > But even it they're not, having the same parsing rules whether static or extern is used is simpler.

    I don't understand what you're trying to say here.

  6. #6
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Objects at file scope are not necessarily extern by default, assuming you mean that they behave as though they have the extern storage-class specifier.
    Code:
    int var1 = 0;
    extern int var2 = 0;
    
    int var3;
    extern int var4;
    Here var1 and var2 are the same thing: Definitions of an object with external linkage.

    var3 and var4 are not the same. var3, as has been noted, is a tentative definition. Barring any other declarations of it, var3 will be defined and have the value zero. var4's declaration, on the other hand, means that somewhere else there is an external definition called var4.

    To quote the standard: "An external definition is an external declaration that is also a definition of ... an object" (C99 6.9p5).

    The upshot here is that var1, var2, and var3 all are definitions; storage is reserved. var4 is not a definition and thus storage is not reserved. It must be reserved elsewhere if var4 is used.

    File scope objects do, by default, have external linkage, meaning they're visible from other source files. This is not the same as the extern specifier, though!

    If this isn't confusing enough, functions do behave as though they're tagged with the extern specifier unless you mark them as static. Isn't C great?

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    What is an external declaration and an external definition? Does "external" refer to linkage or the keyword?

  8. #8
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    An external declaration is a declaration that's at file scope, regardless of whether the extern specifier is used.

    An external declaration doesn't necessarily have external linkage. An external declaration doesn't necessarily include an extern specifier. And what might be even more perverse, a declaration with the extern specifier doesn't necessarily have external linkage! Assuming this is file scope, all the following are external declarations:
    Code:
    static int a; /* Internal linkage. */
    extern int a; /* Internal linkage, referring to previous "a". */
    extern int b; /* Internal linkage if there is a previous declaration of "b" that is internal, external otherwise. */
    int c;        /* External linkage. */

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Is static int a; at file scope an external declaration?

    Why not not use extern in headers? The only difference I can think of is that you get a linker error if you don't define the variable in your source file if you use extern in the header. Why would that be an advantage?

  10. #10
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by robwhit View Post
    > But even it they're not, having the same parsing rules whether static or extern is used is simpler.

    I don't understand what you're trying to say here.
    There is no good reason to allow multiple declarations for static globals. There is a good reason for extern globals. But it makes for a simpler standard if it's allowed for both.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  11. #11
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Is static int a; at file scope an external declaration?
    Yes.
    Why not not use extern in headers? The only difference I can think of is that you get a linker error if you don't define the variable in your source file if you use extern in the header. Why would that be an advantage?
    You should use extern in a header if you're sharing an object between source files. In one .c file you define the object (that is, don't use extern, and, of course, don't use static). In the header you declare the object with extern, and include it wherever you want to use it, including the .c file that contains the definition.

    If you don't use extern (or static, but that's not especially relevant at this point) in the header, then each source file that includes the header will try to define an object (that has external linkage) with that name, which is bad news. Once more than one source file includes it you'll likely wind up with a linker error for multiple definitions.

  12. #12
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    I don't get a multiple definition error.
    Code:
    $ cat t.c
    #include <stdio.h>
    
    int i = 2;
    
    int func();
    
    int main()
    {
            func();
            printf ("&#37;d\n", i); 
            return 0;
    }
    $ cat t2.c
    int i;
    
    int func ()
    {
            return i = 5;
    }
    $ gcc -pedantic -std=c99 -Wall t.c -c -o t.o
    $ gcc -pedantic -std=c99 -Wall t2.c -c -o t2.o
    $ gcc t.o t2.o
    $ ./a.out
    5
    $
    Last edited by robwhit; 05-19-2008 at 10:23 PM. Reason: changed "redefinition error" to "multiple definition error"

  13. #13
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Code:
    I don't get a multiple definition error.
    Perhaps "likely" is overstating it: it's undefined behavior, so linking errors are not required.

    The relevant part of the standard is this (6.9p5): "If an identifier declared with external linkage is used in an expression ..., somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one."

  14. #14
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Here is the other relevant section:
    Quote Originally Posted by 6.2.2.5
    If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.
    Thanks King Mir and cas.

  15. #15
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    This may or may not be of value, I skim far too much these days, but some of what I gleaned reminded me of yet another Chris Torek post. FWIW.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Extern variables in GAS?
    By Kernel Sanders in forum C Programming
    Replies: 6
    Last Post: 10-20-2008, 10:10 PM
  2. Replies: 16
    Last Post: 10-29-2006, 05:04 AM
  3. problem with extern variables
    By crash88 in forum C Programming
    Replies: 11
    Last Post: 05-05-2006, 01:44 PM
  4. Odd Problem with Linking
    By jamez05 in forum C++ Programming
    Replies: 6
    Last Post: 09-21-2005, 01:49 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