In C, there are 4 categories of identifiers: * labels * tag names (@(struct|union|enum) tag-name@), where all tag names live in one namespace * members of structures and unions * identifiers, type-names and enumeration constants There are 4 kind of scopes: * file scope: outside of parameter lists and blocks * function prototype scope * function scope: labels are visible within the entire function, and declared implicitely * block scope Scoping rules: * labels have function scope * all other identifiers have scope determined by the placement of the identifier * struct/union/enum tags have scopes that begin after their appearance * all other identifiers scopes begins at the end of the corresponding declarator * their scope ends at the end of the block / file / prototype if they are in block/file/prototype scope * inner scope hides (shadows) outer scope Linkage rules: * if an identifier declaration has no linkage, it refers to the unique object declared * if an identifier decl has internal linkage, it refers to the file-scope object with the given name * the specifier `static' declares internal linkage * if an identifier decl has external linkage, it refers to the program scope object with the given name * the specifier `extern' declares external linkage IF no identifier of the given name is visible File-scope function declarations have and implicit `extern` specifier, while file-scope objects have external linkage, unless declared otherwise. * the specifier `extern' denotes the object with the same name which is visible (if there is one) * undefined behaviour if identifier appears with both internal and external linkage Strategy for declarations/definitions: * if there is no identifier * if there is an undefined declaration of the same kind in scope, we define it * if there is an identifier of different kind in scope, we overwrite it and return the old definition It is the clients responsibility to check whether the redefinition is ok * if there is an defined declaration of the same kind in scope, we redefine it and return the old definition