CodeNebula
C++17coreadvanced

Inline Variables

C++17 · Practical Modern · Compiler flag: -std=c++17

Explanation

Variables declared `inline` can be defined in header files without causing multiple-definition linker errors, following the same rules as inline functions. This is essential for header-only libraries.

Real-World Scenario

Define a global configuration constant in a shared header used across multiple translation units in a library.

Quick Snippet

snippet.cpp
// config.h
inline constexpr int MAX_CONNECTIONS = 256;
inline std::string APP_NAME = "MyApp";

Full Example

inline_variables.cpp
// CodeNebula - C++17 Example: Inline Variables
// Compile: g++ -std=c++17 -Wall -Wextra -o example inline_variables.cpp

// Demonstrates inline variables and inline static data members. Before C++17,
// static data members required a separate out-of-class definition. Now, inline
// allows definition directly in the class, and inline global variables can appear
// in headers without ODR violations.

#include <iostream>
#include <string>

// ------------------------------------------------------------------
// 1. inline variable at namespace scope (safe to put in a header)
// ------------------------------------------------------------------
inline const int kMaxConnections = 100;
inline const std::string kAppName = "CodeNebula";

// ------------------------------------------------------------------
// 2. Class with inline static data members (no out-of-class definition needed)
// ------------------------------------------------------------------
struct Config {
    inline static int version = 3;
    inline static std::string mode = "release";
    inline static constexpr double pi = 3.14159265358979;  // constexpr implies inline

    static void print() {
        std::cout << "  version: " << version << std::endl;
        std::cout << "  mode   : " << mode << std::endl;
        std::cout << "  pi     : " << pi << std::endl;
    }
};

// ------------------------------------------------------------------
// 3. Template with inline static member
// ------------------------------------------------------------------
template <typename T>
struct TypeInfo {
    inline static int instance_count = 0;

    TypeInfo()  { ++instance_count; }
    ~TypeInfo() { --instance_count; }
};

// ------------------------------------------------------------------
// 4. inline constexpr for compile-time constants
// ------------------------------------------------------------------
inline constexpr int BUFFER_SIZE = 1024;
inline constexpr char DELIMITER = ',';

int main()
{
    // Namespace-scope inline variables
    std::cout << "=== inline namespace-scope variables ===" << std::endl;
    std::cout << "  kMaxConnections: " << kMaxConnections << std::endl;
    std::cout << "  kAppName       : " << kAppName << std::endl;

    // Class inline static members
    std::cout << "\n=== inline static class members ===" << std::endl;
    Config::print();

    // Modify inline static members
    Config::version = 4;
    Config::mode = "debug";
    std::cout << "\n=== after modification ===" << std::endl;
    Config::print();

    // Template inline static members (each specialization gets its own copy)
    std::cout << "\n=== template inline static members ===" << std::endl;
    TypeInfo<int> a, b, c;
    TypeInfo<double> d;
    std::cout << "  TypeInfo<int>::instance_count   : " << TypeInfo<int>::instance_count << std::endl;
    std::cout << "  TypeInfo<double>::instance_count: " << TypeInfo<double>::instance_count << std::endl;

    // inline constexpr
    std::cout << "\n=== inline constexpr ===" << std::endl;
    std::cout << "  BUFFER_SIZE: " << BUFFER_SIZE << std::endl;
    std::cout << "  DELIMITER  : '" << DELIMITER << "'" << std::endl;

    return 0;
}

/*
Expected output:

=== inline namespace-scope variables ===
  kMaxConnections: 100
  kAppName       : CodeNebula

=== inline static class members ===
  version: 3
  mode   : release
  pi     : 3.14159

=== after modification ===
  version: 4
  mode   : debug
  pi     : 3.14159

=== template inline static members ===
  TypeInfo<int>::instance_count   : 3
  TypeInfo<double>::instance_count: 1

=== inline constexpr ===
  BUFFER_SIZE: 1024
  DELIMITER  : ','
*/
Run command
g++ -std=c++17 -Wall -Wextra -o example inline_variables.cpp