C ++ 17inline変数
この素晴らしいC ++ 17機能により、次のことが可能になります。
main.cpp
#include <cassert>
#include "notmain.hpp"
int main() {
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;
}
コンパイルして実行します。
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アップストリーム。
参照:インライン変数はどのように機能しますか?
インライン変数に関するC ++標準
C ++標準は、アドレスが同じになることを保証します。C ++ 17 N4659標準ドラフト
10.1.6「インライン指定子」:
6インライン関数または外部リンケージを持つ変数は、すべての変換ユニットで同じアドレスを持つ必要があります。
cppreference https://en.cppreference.com/w/cpp/language/inlineは、static指定されていない場合は外部リンクがあると説明しています。
インライン変数の実装
それがどのように実装されているかを観察することができます:
nm main.o notmain.o
を含む:
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
とman nm言うu:
「u」シンボルは、一意のグローバルシンボルです。これは、ELFシンボルバインディングの標準セットに対するGNU拡張です。このようなシンボルの場合、ダイナミックリンカーは、プロセス全体で、この名前とタイプが使用されているシンボルが1つだけであることを確認します。
したがって、このための専用のELF拡張機能があることがわかります。
GCC 7.4.0、Ubuntu18.04でテスト済み。