diff --git a/1-ProceduralProgramming/0-main.ipynb b/1-ProceduralProgramming/0-main.ipynb
index 6cbe872cf3dde22cf60e944faf955fd193d5f83b..003c9ef21908b1b3997c819b5c7e9c4049d880c0 100644
--- a/1-ProceduralProgramming/0-main.ipynb
+++ b/1-ProceduralProgramming/0-main.ipynb
@@ -19,7 +19,8 @@
     "    * [TP 2](./4b-TP.ipynb)\n",
     "* [Dynamic allocation](./5-DynamicAllocation.ipynb)\n",
     "* [Input/output](./6-Streams.ipynb)\n",
-    "    * [TP 3](./6b-TP.ipynb)"
+    "    * [TP 3](./6b-TP.ipynb)\n",
+    "* [Static and constexpr](./7-StaticAndConstexpr.ipynb)"
    ]
   },
   {
diff --git a/1-ProceduralProgramming/7-StaticAndConstexpr.ipynb b/1-ProceduralProgramming/7-StaticAndConstexpr.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..24bd3c71df17ec4c47ca52b3f272e1f6bf8d7428
--- /dev/null
+++ b/1-ProceduralProgramming/7-StaticAndConstexpr.ipynb
@@ -0,0 +1,304 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# [Getting started in C++](/) - [Procedural programming](./0-main.ipynb) - [Static and constexpr](./7-StaticAndConstexpr.ipynb)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "toc": true
+   },
+   "source": [
+    "<h1>Table of contents<span class=\"tocSkip\"></span></h1>\n",
+    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#Static-keyword\" data-toc-modified-id=\"Static-keyword-1\">Static keyword</a></span></li><li><span><a href=\"#Constexpr\" data-toc-modified-id=\"Constexpr-2\">Constexpr</a></span></li></ul></div>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Static keyword"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "`static` may be seen as _at compile time_, whereas `dynamic` may be seen as _at runtime_.\n",
+    "\n",
+    "A reply to this [StackOverflow question](https://stackoverflow.com/questions/572547/what-does-static-mean-in-c) gives a rather good summary of what `static` means in C (we shall see [later](./2-ObjectProgramming/5-static.ipynb) a C++-only keyword that unfortunately share the same moniker):\n",
+    "\n",
+    "* Static defined local variables do not lose their value between function calls. In other words they are global variables, but scoped to the local function they are defined in.\n",
+    "* Static global variables are not visible outside of the C file they are defined in.\n",
+    "* Static functions are not visible outside of the C file they are defined in.\n",
+    "\n",
+    "Only the first one is really relevant in C++, as for quantities that should be accessible only in the current file C++ provides a concept of his own: the [**unnamed namespace**](../6-InRealEnvironment/5-Namespace.ipynb#Unnamed-namespace).\n",
+    "\n",
+    "Let's see the remaining case in action:\n",
+    "\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "void FunctionWithStatic()\n",
+    "{\n",
+    "    static int n = 0; // This initialisation occurs only at first call\n",
+    "                      // But `n` is not destroyed when the end bracket is reached and remains available\n",
+    "                      // in subsequent calls. However, `n` is available only inside this function.\n",
+    "    std::cout << \"The function has been called \" << ++n << \" times.\" << std::endl;    \n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{\n",
+    "    for (int i = 0; i < 5; ++i)\n",
+    "        FunctionWithStatic();    \n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "It might be used for instance if you need to initialize something on the very first call of a function:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// Pseudo-code\n",
+    "\n",
+    "void FunctionWithStatic()\n",
+    "{\n",
+    "    static bool is_first_call = true;\n",
+    "    \n",
+    "    if (is_first_call)\n",
+    "    {\n",
+    "        // Init stuff here on first call only, for instance something that requires heavy computation.\n",
+    "        // ...        \n",
+    "        is_first_call = false;\n",
+    "    }\n",
+    "    \n",
+    "    // ... code executed at each call\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Constexpr\n",
+    "\n",
+    "Let's consider the STL container `std::array`, which is the container of choice to store an array which size is known *at compile time* (containers will be seen more in depth in a [future notebook](./notebooks/5-UsefulConceptsAndSTL/3-Containers.ipynb))."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <array>\n",
+    "\n",
+    "std::array<double, 3ul> my_array;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now imagine we want to init such an array with a size that results from a computation; let's say a Fibonacci series:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// Recursive function - Xeus cling may not appreciate if you call this cell several times.\n",
+    "\n",
+    "auto fibonacci (std::size_t n) \n",
+    "{\n",
+    "    if (n == 0)\n",
+    "        return 0;\n",
+    "    if (n == 1)\n",
+    "        return 1;\n",
+    "    \n",
+    "    return fibonacci(n-1) + fibonacci(n-2);\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "std::cout << fibonacci(5) << std::endl;\n",
+    "std::cout << fibonacci(10) << std::endl;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <array>\n",
+    "std::array<double, fibonacci(4)> my_fibonacci_4_array; // COMPILATION ERROR!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "This doesn't seem outlandish: a computation is involved and this computation happens at runtime - even if in fact all the required elements to perform it were available at runtime (there were for instance no argument read from command line involved).\n",
+    "\n",
+    "In C++ 03, you had two choices to resolve this\n",
+    "\n",
+    "- Using a macro...\n",
+    "- Or using [metaprogramming](./4-Templates/4-Metaprogramming.ipynb) which is a tad overkill... (and involves boilerplate code).\n",
+    "\n",
+    "C++ introduced the keyword `constexpr`, which indicates something happens at compile time. It might be used for just a variable, or for more complicated construct such as functions or classes. The only requirement is that all the subparts used are themselves `constexpr`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "constexpr auto fibonacci_const (std::size_t n) \n",
+    "{\n",
+    "    if (n == 0)\n",
+    "        return 0;\n",
+    "    if (n == 1)\n",
+    "        return 1;\n",
+    "    \n",
+    "    return fibonacci_const(n-1) + fibonacci_const(n-2);\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <array>\n",
+    "constexpr auto  fibonacci_index = 4ul;\n",
+    "std::array<double, fibonacci_const(fibonacci_index)> my_fibonacci_4_array; "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "`constexpr` function may also be used as runtime function, but in this case their results can't of course be used at compile time."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "int i = 7;\n",
+    "++i; // i is by no stretch a compile time variable!\n",
+    "\n",
+    "std::cout << fibonacci_const(7) << std::endl; // ok!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "`constexpr` becomes increasingly powerful over time:\n",
+    "\n",
+    "- The function `fibonacci_const` above does not in fact work before C++ 14: this version of the standard introduced the possibility to provide several `return` in a `constexpr` function.\n",
+    "- `constexpr` is added wherever possible in the STL. This is still a work in progress: if you look for instance the [CppReference page](https://en.cppreference.com/w/cpp/algorithm/count) for `std::count` algorithm, you will see this algorithm becomes `constexpr` in C++ 20."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "\n",
+    "© _CNRS 2016_ - _Inria 2018-2021_   \n",
+    "_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_  \n",
+    "_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_\n",
+    "\n"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++17",
+   "language": "C++17",
+   "name": "xcpp17"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "17"
+  },
+  "latex_envs": {
+   "LaTeX_envs_menu_present": true,
+   "autoclose": false,
+   "autocomplete": true,
+   "bibliofile": "biblio.bib",
+   "cite_by": "apalike",
+   "current_citInitial": 1,
+   "eqLabelWithNumbers": true,
+   "eqNumInitial": 1,
+   "hotkeys": {
+    "equation": "Ctrl-E",
+    "itemize": "Ctrl-I"
+   },
+   "labels_anchors": false,
+   "latex_user_defs": false,
+   "report_style_numbering": false,
+   "user_envs_cfg": false
+  },
+  "toc": {
+   "base_numbering": 1,
+   "nav_menu": {},
+   "number_sections": false,
+   "sideBar": true,
+   "skip_h1_title": true,
+   "title_cell": "Table of contents",
+   "title_sidebar": "Contents",
+   "toc_cell": true,
+   "toc_position": {},
+   "toc_section_display": true,
+   "toc_window_display": true
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/2-ObjectProgramming/5-static.ipynb b/2-ObjectProgramming/5-static.ipynb
index 839353352b87d79e9a0173a92224807e0491bd85..ae6b2ed23a0fa7638316dc9616750a5cd8324e56 100644
--- a/2-ObjectProgramming/5-static.ipynb
+++ b/2-ObjectProgramming/5-static.ipynb
@@ -23,76 +23,9 @@
    "source": [
     "## Static in C\n",
     "\n",
-    "We haven't dealt yet with the keyword `static`, which exists in C and could have been adressed in the procedural part of this lecture.\n",
+    "As a reminder, we have seen in a [previous notebook](./1-ProceduralProgramming/7-StaticAndConstexpr.ipynb#Static-keyword) the `static` keyword inherited from C. \n",
     "\n",
-    "As the C++ concept of **static method** uses up the same keyword and is not entirely related (even if both may be intertwined as we shall see in the [last section](./5-static.ipynb#Static-order-initialization-fiasco---and-its-fix)), we shall first review the C concept before studying the C++ one.\n",
-    "\n",
-    "First of all, `static` may be seen as _at compile time_, whereas `dynamic` may be seen as _at runtime_.\n",
-    "\n",
-    "A reply to this [StackOverflow question](https://stackoverflow.com/questions/572547/what-does-static-mean-in-c) gives a rather good summary of what `static` means in C:\n",
-    "\n",
-    "* Static defined local variables do not lose their value between function calls. In other words they are global variables, but scoped to the local function they are defined in.\n",
-    "* Static global variables are not visible outside of the C file they are defined in.\n",
-    "* Static functions are not visible outside of the C file they are defined in.\n",
-    "\n",
-    "Only the first one is really relevant in C++, as for quantities that should be accessible only in the current file C++ provides a concept of his own: the [**unnamed namespace**](../6-InRealEnvironment/5-Namespace.ipynb#Unnamed-namespace).\n",
-    "\n",
-    "Let's see the remaining case in action:\n",
-    "\n",
-    "\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "#include <iostream>\n",
-    "\n",
-    "void FunctionWithStatic()\n",
-    "{\n",
-    "    static int n = 0; // This initialisation occurs only at first call\n",
-    "                      // But `n` is not destroyed when the end bracket is reached and remains available\n",
-    "                      // in subsequent calls. However, `n` is available only inside this function.\n",
-    "    std::cout << \"The function has been called \" << ++n << \" times.\" << std::endl;    \n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "{\n",
-    "    for (int i = 0; i < 3; ++i)\n",
-    "        FunctionWithStatic();    \n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "It might be used for instance if you need to initialize something on the very first call of a function:\n",
-    "\n",
-    "````\n",
-    "void FunctionWithStatic()\n",
-    "{\n",
-    "    static bool is_first_call = true;\n",
-    "    \n",
-    "    if (is_first_call)\n",
-    "    {\n",
-    "        // Init stuff here on first call only\n",
-    "        ...        \n",
-    "        is_first_call = false;\n",
-    "    }\n",
-    "    \n",
-    "    ... // code executed at each call\n",
-    "}\n",
-    "\n",
-    "````"
+    "What follows is the same  keyword used in a very different context (even if the one we already know will pop up in an idion presented here).\n"
    ]
   },
   {