C ++ 17 inline variables
This amazing C ++ 17 feature allows us to:
- it is convenient to use only one memory address for each constant
- save it as
constexpr : How to declare constexpr extern? - do it in one line from one header
main.cpp
#include <cassert> #include "notmain.hpp" int main() { // Both files see the same memory address. assert(¬main_i == notmain_func()); assert(notmain_i == 42); }
notmain.hpp
#ifndef NOTMAIN_HPP #define NOTMAIN_HPP inline constexpr int notmain_i = 42; const int* notmain_func(); #endif
notmain.cpp
#include "notmain.hpp" const int* notmain_func() { return ¬main_i; }
Compile and run:
Compile and run:
g++ -c -o notmain.o -std=c++17 -Wall -Wextra -pedantic notmain.cpp g++ -c -o main.o -std=c++17 -Wall -Wextra -pedantic main.cpp g++ -o main -std=c++17 -Wall -Wextra -pedantic main.o notmain.o ./main
GitHub upstream . See also: How do built-in variables work?
C ++ standard for built-in variables
The C ++ standard ensures that addresses are the same. C ++ 17 Standard project N4659 10.1.6 " Built-in specifier":
6 A built-in function or a variable with external communication must have the same address in all translation units.
cppreference https://en.cppreference.com/w/cpp/language/inline explains that if static not set, then it has an external connection.
Implementing Inline Variables
We can observe how this is implemented with:
nm main.o notmain.o
which contains:
main.o: U _GLOBAL_OFFSET_TABLE_ U _Z12notmain_funcv 0000000000000028 r _ZZ4mainE19__PRETTY_FUNCTION__ U __assert_fail 0000000000000000 T main 0000000000000000 u notmain_i notmain.o: 0000000000000000 T _Z12notmain_funcv 0000000000000000 u notmain_i
and man nm talks about u :
The "U" Symbol is a unique global symbol. This is a GNU extension for the standard ELF character binding set. For such a symbol, the dynamic linker will ensure that there is only one symbol with this name and type throughout the process.
So, we see that there is a dedicated ELF extension for this.
Ciro Santilli ๆฐ็ ๆน้ ไธญๅฟ ๅ
ญๅ ไบไปถ ๆณ่ฝฎๅ
source share