Variables, Scopes and Namespaces: Constexpr Variables#

Adapted from: “Learn Modern C++” by cpptutor: Learn Modern C++: Variables, Scopes and Namespaces

Program that Demonstrates Constexpr Variables#

// 02-constexpr.cpp : introducing the constexpr keyword
 
#include <print>
#include <cmath>
using namespace std;
 
// constexpr double PI1 = acos(-1.0);
constexpr double PI1 = 3.14159265358979323846; // Hardcoded value because compiler can not evaluate acos(-1.0) at compile time
constexpr double PI2 = 22.0 / 7.0;
 
static_assert(PI1 > 3.141 && PI1 < 3.143);
static_assert(PI2 > 3.141 && PI2 < 3.143);
 
int main() {
    println("PI1 = {}", PI1);
    println("PI2 = {}", PI2);
}

Explanation of the Above Code#

This C++ code demonstrates the use of the constexpr keyword, which is used to define compile-time constants. Here’s a breakdown of the code:

Code Explanation:#

  1. Headers and Namespace:

    #include <print>
    #include <cmath>
    using namespace std;
    
    • <print>: A C++23 header that provides the println function for formatted output.

    • <cmath>: Provides mathematical functions like acos.

    • using namespace std;: Allows usage of standard library functions without prefixing them with std::.

  2. constexpr Variables:

    constexpr double PI1 = acos(-1.0);
    constexpr double PI2 = 22.0 / 7.0;
    
    • constexpr ensures that the values of PI1 and PI2 are computed at compile time.

    • PI1 is calculated using acos(-1.0), which is a precise mathematical computation for π (pi).

    • PI2 is an approximation of π using the fraction 22/7.

  3. Static Assertions:

    static_assert(PI1 > 3.141 && PI1 < 3.143);
    static_assert(PI2 > 3.141 && PI2 < 3.143);
    
    • static_assert checks conditions at compile time.

    • These assertions ensure that both PI1 and PI2 fall within the range of valid π values (between 3.141 and 3.143).

    • If the conditions fail, the program will not compile.

  4. Main Function:

    int main() {
        println("PI1 = {}", PI1);
        println("PI2 = {}", PI2);
    }
    
    • The main function prints the values of PI1 and PI2 using the println function from <print>.

    • {} is a placeholder for the values of PI1 and PI2.

Key Concepts:#

  • constexpr: Ensures that variables are evaluated at compile time, making the program more efficient.

  • static_assert: Validates conditions during compilation, preventing runtime errors.

  • Precision of π: PI1 is more precise than PI2 because acos(-1.0) is mathematically accurate, while 22/7 is an approximation.

Output:#

If compiled and run, the program will output:

PI1 = 3.141592653589793
PI2 = 3.142857142857143

Compile and Run Code#

Use Python to Change to Working Directory#

import os
root_dir = os.getcwd()
code_dir = root_dir + "/" + "Cpp_Code/02_Variables_Scopes_and_Namespaces"
os.chdir(code_dir)

Use Docker to Compile the Code in a C++23 Environment#

!docker run --rm -v $(pwd):/app cpp23-clang18:latest clang++-18 -std=c++23 -stdlib=libc++ /app/02-constexpr.cpp -o /app/02-constexpr

Use Docker to Run Executable in a C++23 Environment#

!docker run --rm -v $(pwd):/app cpp23-clang18:latest ./02-constexpr
PI1 = 3.141592653589793
PI2 = 3.142857142857143