Thread: Real example of extern variable

  1. #16
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,791
    @Player777 I think that it's apparent that this is a complicated subject and to be sure about things you should always be explicit. Although not strictly correct I will use the term 'file' below to keep things simple.

    Code:
    /* at "global scope" */
    
    int global;  /* this is the global. You can access it from other files by using extern int global; */
    Code:
    /* in another file */
    
    extern int global; /* You're saying that 'global' is in another file somewhere */
    Code:
    static int global2;  /* You're saying that global2 is only accessible in this specific file. You can't access it from another file */

  2. #17
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,791
    Quote Originally Posted by laserlight View Post
    That's not a problem; it's a technical description of when and how one or more tentative definitions in a translation unit are coalesced into a single definition.


    The program has two translation units. In each translation unit, there is a tentative definition for the same identifier with external linkage, resulting in a definition each. An identifier with external linkage shall only be defined exactly once (or at most once, if unused) across the entire program. Consequently, it has been defined twice. So, why do you think that there's no undefined behaviour?
    I've changed my mind and now think it's undefined as you said. See my edit (J.5.11p1).

    Edit: To be fair I've been discussing this for 2 hours now with very experienced C programmers without consensus and it was only after 2 hours that someone pointed out J.5.11p1...
    Last edited by Hodor; 02-07-2020 at 05:23 AM.

  3. #18
    Registered User Sir Galahad's Avatar
    Join Date
    Nov 2016
    Location
    The Round Table
    Posts
    277
    Code:
    /* file1.c */
    
    #include<stdio.h>
     
    int Global_Variable = 12;
    void SomeFunction(void);        
     
    int main(void) 
    {  
     SomeFunction();
     printf("%d\n", Global_Variable);
     return 0;
    }
    
    /* file2.c */
    
    int Global_Variable;  
     
    void SomeFunction(void) 
    {       
     ++Global_Variable;
    }
    Output: 13

    Code:
    /* file1.c */
    
    #include<stdio.h>
     
    int Global_Variable;
    void SomeFunction(void);        
     
    int main(void) 
    {  
     SomeFunction();
     printf("%d\n", Global_Variable);
     return 0;
    }
    
    /* file2.c */
    
    int Global_Variable = 24;  
     
    void SomeFunction(void) 
    {       
     ++Global_Variable;
    }
    Output: 25

    Compilers have pretty much always supported that convention though haven't they? It definitely isn't the really worrisome kind of undefined behaviour anyway. Not like dangling pointers, uninitialized variables, bad casts due to CPU alignment and or endianness issues, signed shifts, division by zero errors. This is more like "undefined but implied behaviour".

  4. #19
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,791
    Quote Originally Posted by Sir Galahad View Post
    Code:
    /* file1.c */
    
    #include<stdio.h>
     
    int Global_Variable = 12;
    void SomeFunction(void);        
     
    int main(void) 
    {  
     SomeFunction();
     printf("%d\n", Global_Variable);
     return 0;
    }
    
    /* file2.c */
    
    int Global_Variable;  
     
    void SomeFunction(void) 
    {       
     ++Global_Variable;
    }
    Output: 13

    Code:
    /* file1.c */
    
    #include<stdio.h>
     
    int Global_Variable;
    void SomeFunction(void);        
     
    int main(void) 
    {  
     SomeFunction();
     printf("%d\n", Global_Variable);
     return 0;
    }
    
    /* file2.c */
    
    int Global_Variable = 24;  
     
    void SomeFunction(void) 
    {       
     ++Global_Variable;
    }
    Output: 25

    Compilers have pretty much always supported that convention though haven't they? It definitely isn't the really worrisome kind of undefined behaviour anyway. Not like dangling pointers, uninitialized variables, bad casts due to CPU alignment and or endianness issues, signed shifts, division by zero errors. This is more like "undefined but implied behaviour".
    Well, the compilers have been doing it since at least 1994 it seems. I'm tempted to compile the test with Lattice C on my Amiga but I can guess that it will behave the same. It may as well be de facto standard TBH; they can't change it now because it appears to have been the common interpretation for at least 26 years. Changing it would break too much. That said I'd always use extern type blah. Despite that and despite the appendix I think there is room enough in the standard to say it's not UB. Why else would they bury the UB statement in an appendix (without a reference to the appendix in the body of the standard)? The sections of the C standard regarding how this behaves is poorly worded and ambiguous in my, and others, opinion. If it was truly unambiguously undefined behaviour they'd cross reference to the appendix. Seems slack.

    Edit: The reason I say it seems slack is that for most under- and post-graduate papers appendices are, generally, not even marked. An ISO standard should adhere to the same principle; i.e. if it's UB it should not be in an appendix or annex it should be in the body of the document
    Last edited by Hodor; 02-07-2020 at 08:45 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 9
    Last Post: 05-07-2017, 12:29 PM
  2. Replies: 7
    Last Post: 04-10-2017, 01:58 AM
  3. extern variable
    By edesign in forum C Programming
    Replies: 4
    Last Post: 06-10-2009, 05:51 AM
  4. using extern to have a global variable
    By steve1_rm in forum C Programming
    Replies: 3
    Last Post: 01-29-2009, 06:44 AM
  5. extern variable assignment
    By George2 in forum C++ Programming
    Replies: 4
    Last Post: 02-12-2008, 07:41 AM

Tags for this Thread