What changes have to made in the uploaded code if want to check these three types of errors?
The (correct) terms you are using are the ones in the standard.
For the standard 'linkage' means (very very simply) 'the behaviour when an identifier is declared more then once in a different or the same scope'.
This is a bit different, but has of course a strict relationship with what a linker does: putting together compiled translation units (~= source files) and making sure
that identifier names correspond to the right object (the relevant part is underlined).
The definition of the three linkage type are (summarizing from the C11 standard, Ch 6.2.2):
- All the declaration of an identifier with internal linkage represent the same object or function in the same translation unit.
- All the declaration of an identifier with external linkage represent the same object or function across all the same translation units.
- All the declaration of an identifier with no linkage represent the same entity.
Note the shift of language between internal/external and no linkage: entity is used instead of object or function, as also typedef names, struct tags, function parameters etc. are identifiers with no linkage.
Now, all of this is nice, formally sound and consistent, but some complications (and confusion) are brought by the fact that in C linkage is signified by the keywords
extern and
static (or their absence) that have other semantics related to the storage duration (= time of life) or by where a declaration is found.
Ojects or functions declared with "static" will have internal linkage.
Objects or functions declared with "extern" will have external linkage, if no previous declaration is found.
Objects at file scope, and functions, default to extern.
Objects at block scope default to no linkage.
Example file A:
static int i; /* i has internal linkage */
extern int i; /* Fine, i is still static - compiler will not complain - as the previous declaration takes priority */
File B:
extern int i; /* This is i is not the same as the one above, as that one has internal linkage! */
Other example:
extern int i; /* no previous declaration, i has external linkage */
static int i; /* loud complaining from the compiler: static means internal linkage, but the object has external linkage! */
Note the difference with file A above!
No linkage:
void f(int i); /* i has no linkage */
void f(int i)
{
int j; /* Also j ha no linkage */
extern int k; /* but k has external linkage */
static int n; /* and n has internal linkage */
}