inline vs static for nonmember global variables

Viewed 183

Presume I have a C++ header

utils.h

And I want to have some constant map available in multiple TUs(map is not inside a class, normal global variable/constant).

const std::map<int, std::string> ToString{{1,"1"}, {2, "2"}};

Should I declare it inline or static? In other words:

static const std::map<int, std::string> ToString{{1,"1"}, {2, "2"}};

or

inline const std::map<int, std::string> ToString{{1,"1"}, {2, "2"}};

(AFAIK both will work to prevent ODR violation, static by making the linkage internal, and inline by making it ok to have multiple definitions, but I could be wrong, I often make mistakes wrt ODR).

Note: I want to avoid solutions using extern.

2 Answers

There is another option

// header file main.h

#pragma once

#include <map>
#include <string>

static const auto& get_string_map()
{
    static const std::map<int, std::string> ToString{ {1,"1"}, {2, "2"} };
    return ToString;
}

// implementation file main.cpp

#include <iostream>
#include "main.h"

int main()
{
    auto map = get_string_map();
    std::cout << map.at(1);
}

Great question! AFAIK you can use both to achieve your goal:

// utils.h

#include <map>

static inline const std::map<int, std::string> ToString{{1,"1"}, {2, "2"}};
  • inline hints to the compiler to consolidate all the files that include this header into a single one, thus meeting the ODR. Note: In C++20, inline is just for readability, as the compiler will ignore it if it's not going to improve performance.
  • static forces ToString to be a compile-time value which helps with performance.
Related