diff --git a/clang.md b/clang.md
index 64740369704e795ef344df381c9f9788fb3c3a1f..92d5dd3b9cfbbf3dfafac7ea4dd9f8758d3f03f2 100644
--- a/clang.md
+++ b/clang.md
@@ -8,7 +8,7 @@ We will focus on common errors, caveats and important concepts that might ease y
 
 C only guarantees minimum and relative size of "int", "short" etc... The range that each type can represent depends on the implementation.
 
-The integer data types range in size from at least 8 bits to at least 32 bits. The C99 standard extends this range to include integer sizes of at least 64 bits. 
+The integer data types range in size from at least 8 bits to at least 32 bits. The C99 standard extends this range to include integer sizes of at least 64 bits.
 
 The types are ordered by the width, guaranteeing that _wider_ types are at least as large as _narrower_ types. E.g. `long long int` can represents all values that a `long int` can represent.
 
@@ -87,7 +87,7 @@ int foo(int* p)
     else
         return 0;
 }
- 
+
 int bar()
 {
     int* p = NULL;
@@ -158,7 +158,7 @@ int main() {
     return EXIT_FAILURE;
   }
   free(buf);
-  strcpy(buf, ftr); // UB 
+  strcpy(buf, ftr); // UB
   printf("buf = %s\n", buf);
 
   return EXIT_SUCCESS;
@@ -241,7 +241,7 @@ void foo(void *v) {
 
 ### Void Pointer
 
-We should also know that void pointers can be **casted** into any type of pointer. 
+We should also know that void pointers can be **casted** into any type of pointer.
 
 In C, library functions like `malloc`, `calloc` etc. return void pointers, which we can then cast in to any other type of pointers as we need:
 
@@ -296,8 +296,8 @@ Arrays in C are very primitive:
 
 - An Array in C does not have the information to its own length, not like `arr.length` in other languages
 - Array's bounds are not checked at all
-    - So we can easily access off the end of an array
-    - We muss pass the array and its size together to any function that is going to manipulate it
+  - So we can easily access off the end of an array
+  - We muss pass the array and its size together to any function that is going to manipulate it
 
 ## Strings
 
@@ -357,31 +357,30 @@ Objects declared in file scope have `static` storage duration. The lifetime of t
 
 #### Allocated
 
-`Allocated` storage is allocated and deallocated through library functions on requests, using dynamic memory allocation functions. 
-
+`Allocated` storage is allocated and deallocated through library functions on requests, using dynamic memory allocation functions.
 
 A concrete example of these storage durations:
 
 ```c
 #include <stdio.h>
 #include <stdlib.h>
- 
+
 /* static storage duration */
 int A;
- 
+
 int main(void)
 {
     printf("&A = %p\n", (void*)&A);
- 
+
     /* automatic storage duration */
     int A = 1;   // hides global A
     printf("&A = %p\n", (void*)&A);
- 
+
     /* allocated storage duration */
     int *ptr_1 = malloc(sizeof(int));   /* start allocated storage duration */
     printf("address of int in allocated memory = %p\n", (void*)ptr_1);
     free(ptr_1);                        /* stop allocated storage duration  */
-} 
+}
 ```
 
 ### Dynamic Memory Allocation
@@ -557,3 +556,82 @@ Using the header guard prevents the function definition of `func` being included
 A common practice when picking the identifier to use as a header file guard is to use the salient parts of the file path, filename, and extension, separated by an underscore and written in all capital letters. E.g. `FOO_BAR_BAZ_H` for a file located in `foo/bar/baz.h`.
 
 There are other ways of using the preprocessor directives and macros, this [article](https://en.wikibooks.org/wiki/C_Programming/Preprocessor_directives_and_macros) and [GCC documentation](https://gcc.gnu.org/onlinedocs/cpp/) provide extensive information about them.
+
+## C Program Structure
+
+We've talked about storage duration above. Storage duration and linkage are closely related. In C, you can use the **storage-class specifiers** to specify the storage duration and linkage of an object or a function, they are:
+
+- `auto`: automatic duration and no linkage
+- `register`: automatic duration and no linkage; address of this variable cannot be taken (we won't cover this, it's quite rare )
+- `static`: static duration and internal linkage
+- `extern`: static duration and external linkage
+
+### Linkage
+
+Linkage refers to the ability of an **identifier (variable or function)** to be referred to in other scopes.
+
+C provides three kinds of linkage:
+
+- `none`: The identifier can be referred to only from the scope it is in.
+- `external`: The identifier can be referred to from everywhere in the program. (E.g. from other source file).
+- `internal`: The identifier can only be referred to within the translation unit that contains the declaration.
+
+There are some implicit rules if no storage-class specifier is provided, the defaults are:
+
+- `extern` for all functions
+- `extern` for all objects at file scope
+- `auto` for objects at block scope
+
+Let's look at some examples.
+
+```c
+// flib.h
+#ifndef FLIB_H
+#define FLIB_H
+    void f(void);              // function declaration with external linkage
+    extern int state;          // variable declaration with external linkage
+    static const int size = 5; // definition of a read-only variable with internal linkage
+    enum { MAX = 10 };         // constant definition
+#endif // FLIB_H
+```
+
+```c
+// flib.c
+#include "flib.h"
+static void local_f(int s) {}  // definition with internal linkage (only used in this file)
+static int local_state;        // definition with internal linkage (only used in this file)
+ 
+int state;                     // definition with external linkage (used by main.c)
+void f(void) { local_f(state); } // definition with external linkage (used by main.c)
+```
+
+```c
+// main.c 
+#include "flib.h"
+int main(void)
+{
+    int x[MAX] = {size}; // uses the constant and the read-only variable
+    state = 7;           // modifies state in flib.c
+    f();                 // calls f() in flib.c
+}
+```
+
+#### Special Use of `static`
+
+Declaring a variable at block scope as static creates an identifier with no linkage, but it does give the variable static storage duration:
+
+```c
+#include <stdio.h>
+
+void foo() {
+    static int count = 0; // count has no linkage but has static storage duration
+    printf("Function has been called %d times\n", ++count);
+}
+
+int main() {
+    foo();
+    foo();
+    foo();
+    return 0;
+}
+```