Declaration

Declaration is used to specify the names to the program such as the name of a variable, function, namespace, classes, etc. No name can be used in a program without its declaration. The program elements can be declared multiple times, unlike definition. Multiple declarations can only be achieved when the different declarations are made using the identical format. Declaration is the medium of providing visibility to the program element in the perspective of compilers.

// Declaration example
extern int bar;
extern int g(int, int);
double f(int, double); // extern can be omitted for function declarations
class foo;             // no extern allowed for type declarations

A declaration means (in C) that you are telling the compiler about type, size and in case of function declaration, type and size of its parameters of any variable, or user-defined type or function in your program. No space is reserved in memory for any variable in case of the declaration.

 

Definition

Definition identifies the code or data associated with the name of the variable, function, class, etcetera. The definition is necessarily required by the compiler to allocate the storage space for the declared entity. When a variable is defined it holds an amount of memory consist of several bytes for that variable. A function definition produces code for the function. We can define a program element just once in a program because the definition is a unique specification of a program element.

A definition actually instantiates/implements this identifier. It’s what the linker needs in order to link references to those entities. These are definitions corresponding to the above declarations:

int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
class foo {};

 

Declaring and Defining Variables with Extern

Most of the time, when you declare a variable, you are also providing the definition. It means you are telling the compiler where to create the storage for that variable. For example

int x;
int main()
{
    x = 3;
}

The line int x; both declares and defines the variable; it effectively says, “create a variable named x, of type int. Also, the storage for the variable is that it is a global variable defined in the object file associated with this source file.”

Use of extern is creating a declaration of a variable but NOT defining it; it is saying that the storage for the variable is somewhere else. Technically, you could even write code like this:

extern int x;
int func()
{
    x = 3;
}

int x;

And now you have a declaration of x at the top of the program and a definition at the bottom. Using extern to declare a global variable is pretty much the same thing as using a function declaration to declare a function in a header file.

In fact, if you put a variable into a header file and do not use extern, you will run into the inverse problem of an undefined symbol; you will have a symbol with multiple definitions, with an error like “redefinition of ‘foo'”. This will happen when the linker goes to link together multiple object files.

 

Difference Declaration and Definition

  • An identifier can be declared as often as you want. Thus, the following is legal in C and C++:
    double f(int, double);
    double f(int, double);
    extern double f(int, double); // Same as the two above
    extern double f(int, double);
    
    extern int a;
    extern int a;

    However, it must be defined exactly once. If you forget to define something that’s been declared and referenced somewhere, then the linker doesn’t know what to link references to and complains about a missing symbols. If you define something more than once, then the linker doesn’t know which of the definitions to link references to and complains about duplicated symbols.

  • The declaration serves the purpose of definition in certain cases. For example when the static data member is declared inside a class declaration, in that case, it is not a declaration. Because it generates only one copy for all objects of the class and static data members are the components of the objects of a provided class type.
  • Definition means that in additions to all the things that declaration does, space is additionally reserved in memory.
  • Compiler only needs to have a declaration for something in order to compile a file into an object file, expecting that the linker can find the definition from another file. If no source file ever defines a symbol, but it is declared, you will get errors at link time complaining about undefined symbols.

 

Common Cases

  • If you want to use a function across multiple source files, you should declare the function in one header file (.h) and then put the function definition in one source file (.c or .cpp). All code that uses the function should include just the .h file, and you should link the resulting object files with the object file from compiling the source file.
  • If you want to use a class in multiple files, you should put the class definition in a header file and define the class methods in a corresponding source file.
  • If you want to use a variable in multiple files, you should put the declaration of the variable using the extern keyword in one header file, and then include that header file in all source files that need that variable. Then you should put the definition of that variable in one source file that is linked with all the object files that use that variable.