4

See the comments to see what is being referred as declaration. If the whole variable declaration part was missing, what would be the problem?

Appears that variable definition and initialization either simultaneously or separately like in the example would suffice.

#include <stdio.h>

// Variable declaration:
extern int a, b;
extern int c;
extern float f;

int main () {

   /* variable definition: */
   int a, b;
   int c;
   float f;

   /* actual initialization */
   a = 10;
   b = 20;

   c = a + b;
   printf("value of c : %d \n", c);

   f = 70.0/3.0;
   printf("value of f : %f \n", f);

   return 0;
}
  • 8
    The variables `a`, `b`, etc. in `main()` are not related to `extern int a, b;` etc. If you declare a variable in inner scope with a same name then the resp. variable of outer scope is [eclipsed](https://en.cppreference.com/w/cpp/language/declarations#Notes). (It's still there but you cannot access in inner scope.) – Scheff's Cat Oct 17 '18 at 10:17
  • inner scope is what is located in the main()? – user10517877 Oct 17 '18 at 10:20
  • 5
    Each `{` opens a new scope which ends with the corresponding `}`. `int a; int a;` is invalid -> redeclaration. `int main() { int a; { int a; } }` is not -> variables are declared in different scopes. – Scheff's Cat Oct 17 '18 at 10:22

4 Answers4

3

If the declaration was missing then it would create no problem in main function since the locally defined variables i.e. a,b,c,f will be used in the functionality of main till its scope ends.

The declaration merely tells that the definition lies elsewhere (in some other .c file) or the definition lies after the function main in the same .c file.

Gaurav
  • 1,570
  • 5
  • 17
2

There will be no problem here if the mentioned declaration is missing.

// Variable declaration:
extern int a, b;
extern int c;
extern float f;

This tells the compiler that these variables are defined somewhere else(in another file).

/* variable definition: */
int a, b;
int c;
float f;

This is where you define variables but they are not the same as the external variables you declared since they are in the inner scope of the main function.

The scope is the place where variables live. extern keyword notes that the scope is global. You can define variables with the same name in an inner scope and access only them as you did in the main function but it's not a good practice.

void foo()
{
    int a = 5;
    printf("%d\n", a); // 5

    // Creating an inner scope
    {
        int a = 20;
        printf("%d\n", a); // 20
    }
    printf("%d\n", a); // 5
}

The correct way to use the extern keyword with variables is like this.

//h1.h
extern int global_var;  // Declaration of the variable

//c1.c
#include h1.h
int global_var = 0; // Definition of the global var. Memory is allocated here.

//main.c
#include h1.h
int main()
{
    printf("global var value is %d\n", global_var); // use of the var defined and 
                                                    // initialized in c1.c
    return 0;
}

This program will print 0 since the variable is defined and initialized in c1.c.

Petar Velev
  • 2,305
  • 12
  • 24
1

Extern extends the visibility of the C variables and C functions. so that lets the compiler know that there is another place that those vars are declared and memory was allocated for them elsewhere. for example in another c file. if you compile a c file containing a global var for example: int c = 5; and you create a function on you c file that uses this c var, for example:

int someFunc(void){

return c;}

if you run someFunc in your main and print its return value, you will get 5. but you must compile both c files together. in your program, you only use the locally allocated var declared in your main function.

H.cohen
  • 517
  • 3
  • 9
  • 1
    `extern` does not actually change the visibility. Visibility is a matter of *scope*, and `extern` does not change where in the source text an identifier will be known and can be used. `extern` changes *linkage*. Linkage is a process by which different declarations of the same identifier can be made to refer to the same object. (And, unfortunately, the semantics of `extern` mean it does not always provide external linkage, so explaining it is complicated.) – Eric Postpischil Oct 17 '18 at 12:35
0

When it comes to simple variables, there is really no difference between the declaration and definition. There is a difference when it comes to structs and functions. Here is an example:

// Declarations
struct myStruct;
int foo();

int main() 
{
   ...
}

// Definitions
struct myStruct {
    int a, b;
};

int foo() {
    return 42;
}

In your case, you are hiding the previous declarations so that they are not accessible before the end of the scope. This is commonly called shadowing. It's basically the same thing as this:

int main()
{
    int i=0;
    printf("i: %d\n", i);
    {
        int i=42; // Now the previous i is inaccessible within this scope
        printf("i: %d\n", i);
    }
    // And now it is accessible again
    printf("i: %d\n", i);
}
klutt
  • 30,332
  • 17
  • 55
  • 95
  • "overriding the previous declarations." the identifiers are *hidden*, not overwritten. A commonly used term is *shadowing*. – Swordfish Oct 17 '18 at 12:41
  • 1
    @Swordfish, you wrote *overwritten* instead of *overridden*. Nobody suggested overwriting. That said, you're absolutely correct that the standard term here is **shadowing**. – Toby Speight Oct 17 '18 at 12:54
  • @TobySpeight Sorry, I am not a native speaker. But I think it is understandable from the context what I was trying to say. Note that "shadowing" is not used in the standard. – Swordfish Oct 17 '18 at 12:57
  • I didn't mean "standard"; I should have written something like "conventional". Touche! – Toby Speight Oct 17 '18 at 13:05
  • @Swordfish I picked "overriding" because that is the first that came to my mind, and this is a commonly used term in oop when you write a new version of a superclass method. But you're correct. I have fixed it now. – klutt Oct 18 '18 at 08:56