Loose-Info.com
Last Update 2023/07/27
TOP - 各種テスト - C++ - 識別子

概要

識別子使用可能文字のテスト
GCC-12.2.0における実装ベースの予約語の調査


識別子使用可能文字のテスト


sample.cpp
#include <iostream> int main() { std::cout << "識別子使用可能文字のテスト" << std::endl; int ABCDEFGHIJKLMNOPQRSTUVWXYZ = 12; /* 英大文字 */ int abcdefghijklmnopqrstuvwxyz = 34; /* 英小文字 */ int _ = 56; /* 下線文字 */ int a0123456789 = 78; /* 数字(先頭以外) */ int あいうえお = 90; /* マルチバイト文字 */ std::cout << "ABCDEFGHIJKLMNOPQRSTUVWXYZ = " << ABCDEFGHIJKLMNOPQRSTUVWXYZ << std::endl; std::cout << "abcdefghijklmnopqrstuvwxyz = " << abcdefghijklmnopqrstuvwxyz << std::endl; std::cout << "_ = " << _ << std::endl; std::cout << "a0123456789 = " << a0123456789 << std::endl; std::cout << "あいうえお = " << あいうえお << std::endl; }

実行結果
$ gcc -Wall sample.cpp -lstdc++ $ ./a.out 識別子使用可能文字のテスト ABCDEFGHIJKLMNOPQRSTUVWXYZ = 12 abcdefghijklmnopqrstuvwxyz = 34 _ = 56 a0123456789 = 78 あいうえお = 90

GCC-12.2.0における実装ベースの予約語の調査
(GCC-12.2.0のC++規格(GNU拡張付き)で新しい仕様と考えられる-std=gnu++20を使用したコンパイル))


この項目(識別子・その2)のコードのライセンスに関して
GNU General Public License (GPL)に基づきライセンスされるソフトウェアの改変と考えられる内容となっているため、 本項目のコード(sample.h、sample1.c、sample2.c、sample3.c)は以下のライセンスに基づくものとする。 なお、サンプルコードとしての性格上、コード内へのライセンス関連の記述は省略する。
GPL(GNU General Public License)

sample.h
GCCのソース内のC言語ファミリーの予約語関連の列挙定数、マクロ、構造体の定義を使用してヘッダファイルを作成
ソースコード : gcc-12.2.0 ダウンロード

gcc-12.2.0/gcc/c-family/c-common.h --- 63行目~278行目
enum rid
予約語の列挙定数(C、C++、Objective-C)
gcc-12.2.0/gcc/c-family/c-common.h --- 401行目~408行目
struct c_common_resword
予約語テーブル登録構造体
gcc-12.2.0/gcc/c-family/c-common.h --- 442行目~462行目
無効化マスク
(reswords[i].disable & mask)の結果がtrueの場合は、reswords[i]は無効
gcc-12.2.0/gcc/c-family/c-common.cc 343行目~603行目
const struct c_common_resword c_common_reswords[]
予約語テーブル
#include <ansidecl.h> /* ---------- gcc-12.2.0/gcc/c-family/c-common.h 63行目~278行目 ---------- */ enum rid { /* Modifiers: */ /* C, in empirical order of frequency. */ RID_STATIC = 0, RID_UNSIGNED, RID_LONG, RID_CONST, RID_EXTERN, RID_FIRST_PATTR = RID_GETTER, RID_LAST_PATTR = RID_NULL_RESETTABLE }; /* ---------- gcc-12.2.0/gcc/c-family/c-common.h 63行目~278行目 ---------- */ /* ---------- gcc-12.2.0/gcc/c-family/c-common.h 401行目~408行目 ---------- */ /* An entry in the reserved keyword table. */ struct c_common_resword { const char *const word; ENUM_BITFIELD(rid) const rid : 16; const unsigned int disable : 16; }; /* ---------- gcc-12.2.0/gcc/c-family/c-common.h 401行目~408行目 ---------- */ /* ---------- gcc-12.2.0/gcc/c-family/c-common.h 442行目~462行目 ---------- */ #define D_CONLY 0x0001 /* C only (not in C++). */ #define D_CXXONLY 0x0002 /* C++ only (not in C). */ #define D_CXX_MODULES_FLAGS (D_CXXONLY | D_CXX_MODULES) #define D_CXX_COROUTINES_FLAGS (D_CXXONLY | D_CXX_COROUTINES) /* ---------- gcc-12.2.0/gcc/c-family/c-common.h 442行目~462行目 ---------- */ /* ---------- gcc-12.2.0/gcc/c-family/c-common.cc 343行目~603行目 --------- */ const struct c_common_resword c_common_reswords[] = { { "_Alignas", RID_ALIGNAS, D_CONLY }, { "_Alignof", RID_ALIGNOF, D_CONLY }, { "nonnull", RID_NONNULL, D_OBJC }, { "null_resettable", RID_NULL_RESETTABLE, D_OBJC }, }; /* ---------- gcc-12.2.0/gcc/c-family/c-common.cc 343行目~603行目 --------- */

sample1.cpp
GCCのC言語ファミリー全体の予約語から、(reswords[i].disable & mask)の結果がtrueとなるキーワードを、 int型変数の識別子として定義・使用するコードとして出力
#include <iostream> #include "sample.h" int main() { int n_reswords = (sizeof(c_common_reswords)) / (sizeof (struct c_common_resword)); for (int i=0; i<n_reswords; i++) { if (c_common_reswords[i].disable & (D_CONLY | D_C99 | D_OBJC | D_TRANSMEM)) { std::cout << "int " << c_common_reswords[i].word << " = " << c_common_reswords[i].rid << "; "; std::cout << "std::cout << \"" << c_common_reswords[i].word << " = \" << " << c_common_reswords[i].word << " << std::endl;" << std::endl; } } }

実行結果
$ gcc -Wall sample1.cpp -lstdc++ $ ./a.out int _Alignas = 99; std::cout << "_Alignas = " << _Alignas << std::endl; int _Alignof = 66; std::cout << "_Alignof = " << _Alignof << std::endl; int nonnull = 40; std::cout << "nonnull = " << nonnull << std::endl; int null_resettable = 41; std::cout << "null_resettable = " << null_resettable << std::endl;

sample2.cpp
上記sample1.cの出力内容から作成したコード
青色部はsample1.cで生成されたコード
コンパイルの実行時にエラーが発生しなければ、当該キーワードは識別子として使用可能と確認される
#include <iostream> int main() { int _Alignas = 99; std::cout << "_Alignas = " << _Alignas << std::endl; int _Alignof = 66; std::cout << "_Alignof = " << _Alignof << std::endl; int _Atomic = 14; std::cout << "_Atomic = " << _Atomic << std::endl; int _Bool = 108; std::cout << "_Bool = " << _Bool << std::endl; int _Imaginary = 42; std::cout << "_Imaginary = " << _Imaginary << std::endl; int _Float16 = 85; std::cout << "_Float16 = " << _Float16 << std::endl; int _Float32 = 86; std::cout << "_Float32 = " << _Float32 << std::endl; int _Float64 = 87; std::cout << "_Float64 = " << _Float64 << std::endl; int _Float128 = 88; std::cout << "_Float128 = " << _Float128 << std::endl; int _Float32x = 89; std::cout << "_Float32x = " << _Float32x << std::endl; int _Float64x = 90; std::cout << "_Float64x = " << _Float64x << std::endl; int _Float128x = 91; std::cout << "_Float128x = " << _Float128x << std::endl; int _Decimal32 = 82; std::cout << "_Decimal32 = " << _Decimal32 << std::endl; int _Decimal64 = 83; std::cout << "_Decimal64 = " << _Decimal64 << std::endl; int _Decimal128 = 84; std::cout << "_Decimal128 = " << _Decimal128 << std::endl; int _Fract = 92; std::cout << "_Fract = " << _Fract << std::endl; int _Accum = 93; std::cout << "_Accum = " << _Accum << std::endl; int _Sat = 17; std::cout << "_Sat = " << _Sat << std::endl; int _Static_assert = 178; std::cout << "_Static_assert = " << _Static_assert << std::endl; int _Noreturn = 13; std::cout << "_Noreturn = " << _Noreturn << std::endl; int _Generic = 100; std::cout << "_Generic = " << _Generic << std::endl; int _Thread_local = 16; std::cout << "_Thread_local = " << _Thread_local << std::endl; int __auto_type = 94; std::cout << "__auto_type = " << __auto_type << std::endl; int __builtin_call_with_static_chain = 95; std::cout << "__builtin_call_with_static_chain = " << __builtin_call_with_static_chain << std::endl; int __builtin_choose_expr = 73; std::cout << "__builtin_choose_expr = " << __builtin_choose_expr << std::endl; int __builtin_complex = 75; std::cout << "__builtin_complex = " << __builtin_complex << std::endl; int __builtin_tgmath = 79; std::cout << "__builtin_tgmath = " << __builtin_tgmath << std::endl; int __builtin_types_compatible_p = 74; std::cout << "__builtin_types_compatible_p = " << __builtin_types_compatible_p << std::endl; int __GIMPLE = 96; std::cout << "__GIMPLE = " << __GIMPLE << std::endl; int __PHI = 97; std::cout << "__PHI = " << __PHI << std::endl; int __RTL = 98; std::cout << "__RTL = " << __RTL << std::endl; int restrict = 12; std::cout << "restrict = " << restrict << std::endl; int synchronized = 192; std::cout << "synchronized = " << synchronized << std::endl; int atomic_noexcept = 190; std::cout << "atomic_noexcept = " << atomic_noexcept << std::endl; int atomic_cancel = 191; std::cout << "atomic_cancel = " << atomic_cancel << std::endl; int atomic_commit = 102; std::cout << "atomic_commit = " << atomic_commit << std::endl; int compatibility_alias = 196; std::cout << "compatibility_alias = " << compatibility_alias << std::endl; int defs = 197; std::cout << "defs = " << defs << std::endl; int encode = 193; std::cout << "encode = " << encode << std::endl; int end = 194; std::cout << "end = " << end << std::endl; int implementation = 215; std::cout << "implementation = " << implementation << std::endl; int interface = 214; std::cout << "interface = " << interface << std::endl; int protocol = 202; std::cout << "protocol = " << protocol << std::endl; int selector = 203; std::cout << "selector = " << selector << std::endl; int finally = 207; std::cout << "finally = " << finally << std::endl; int optional = 209; std::cout << "optional = " << optional << std::endl; int required = 210; std::cout << "required = " << required << std::endl; int property = 211; std::cout << "property = " << property << std::endl; int package = 201; std::cout << "package = " << package << std::endl; int synthesize = 212; std::cout << "synthesize = " << synthesize << std::endl; int dynamic = 213; std::cout << "dynamic = " << dynamic << std::endl; int bycopy = 26; std::cout << "bycopy = " << bycopy << std::endl; int byref = 27; std::cout << "byref = " << byref << std::endl; int in = 23; std::cout << "in = " << in << std::endl; int inout = 25; std::cout << "inout = " << inout << std::endl; int oneway = 28; std::cout << "oneway = " << oneway << std::endl; int out = 24; std::cout << "out = " << out << std::endl; int assign = 33; std::cout << "assign = " << assign << std::endl; int atomic = 36; std::cout << "atomic = " << atomic << std::endl; int copy = 35; std::cout << "copy = " << copy << std::endl; int getter = 29; std::cout << "getter = " << getter << std::endl; int nonatomic = 37; std::cout << "nonatomic = " << nonatomic << std::endl; int readonly = 31; std::cout << "readonly = " << readonly << std::endl; int readwrite = 32; std::cout << "readwrite = " << readwrite << std::endl; int retain = 34; std::cout << "retain = " << retain << std::endl; int setter = 30; std::cout << "setter = " << setter << std::endl; int null_unspecified = 38; std::cout << "null_unspecified = " << null_unspecified << std::endl; int nullable = 39; std::cout << "nullable = " << nullable << std::endl; int nonnull = 40; std::cout << "nonnull = " << nonnull << std::endl; int null_resettable = 41; std::cout << "null_resettable = " << null_resettable << std::endl; }

実行結果
$ gcc -Wall -std=gnu++20 sample2.cpp -lstdc++ <--- コンパイル時のエラー無し $ ./a.out _Alignas = 99 <--- 以降、全出力行のキーワードが予約語ではなく、整数型変数名として使用されている事を確認 _Alignof = 66 nonnull = 40 null_resettable = 41
(参考) sample1.cのマスクを個別に設定した出力コードを使用した際のコンパイル実行結果(FAILはエラー発生)
無効化マスク gnu17 gnu99
D_CONLY PASS PASS
D_CXXONLY FAIL FAIL
D_C99 PASS PASS
D_CXX11 FAIL FAIL
D_EXT FAIL FAIL
D_EXT89 FAIL FAIL
D_ASM FAIL FAIL
D_OBJC PASS PASS
D_CXX_OBJC FAIL FAIL
D_CXXWARN FAIL FAIL
D_CXX_CONCEPTS PASS FAIL
D_TRANSMEM PASS PASS
D_CXX_CHAR8_T PASS FAIL
D_CXX20 警告 FAIL
D_CXX_COROUTINES PASS FAIL
D_CXX_MODULES FAIL FAIL
D_CXX_CONCEPTS_FLAGS FAIL FAIL
D_CXX_CHAR8_T_FLAGS FAIL FAIL
D_CXX_MODULES_FLAGS FAIL FAIL
D_CXX_COROUTINES_FLAGS FAIL FAIL

sample3.cpp
上記sample2.cpp出力結果には含まれない、実装されているコンパイラ(GCC)の予約語リストを出力
#include <iostream> #include <iomanip> #include "sample.h" int main() { int n_reswords = (sizeof(c_common_reswords)) / (sizeof (struct c_common_resword)); for (int i=0; i<n_reswords; i++) { if (!(c_common_reswords[i].disable & (D_CONLY | D_C99 | D_OBJC | D_TRANSMEM))) { std::cout << std::setw(3) << std::setfill('0') << c_common_reswords[i].rid << std::uppercase << std::hex << " " << std::setw(4) << std::setfill('0') << c_common_reswords[i].disable << std::dec << " " << c_common_reswords[i].word << std::endl; } } }

実行結果
出力順 : 予約語の列挙定数ridの値(整数値)、無効マスク値、予約語文字列
$ gcc -Wall sample3.cpp -lstdc++ $ ./a.out 015 0000 _Complex <--- 以降、GCC-12.2.0のC言語実装(オプション無しコンパイル時)に関する予約語 105 0000 __FUNCTION__ 106 0000 __PRETTY_FUNCTION__ 066 0000 __alignof 066 0000 __alignof__ 064 0000 __asm 064 0000 __asm__ 067 0000 __attribute 067 0000 __attribute__ 137 0002 __bases 136 0002 __builtin_addressof 149 0002 __builtin_bit_cast 078 0000 __builtin_convertvector 080 0000 __builtin_has_attribute 138 0002 __builtin_launder 081 0000 __builtin_assoc_barrier 076 0000 __builtin_shuffle 077 0000 __builtin_shufflevector 121 0000 __builtin_offsetof 068 0000 __builtin_va_arg 015 0000 __complex 015 0000 __complex__ 003 0000 __const 003 0000 __const__ 179 0002 __constinit 175 0002 __decltype 139 0002 __direct_bases 069 0000 __extension__ 107 0000 __func__ 140 0002 __has_nothrow_assign 141 0002 __has_nothrow_constructor 142 0002 __has_nothrow_copy 143 0002 __has_trivial_assign 144 0002 __has_trivial_constructor 145 0002 __has_trivial_copy 146 0002 __has_trivial_destructor 147 0002 __has_unique_object_representations 148 0002 __has_virtual_destructor 070 0000 __imag 070 0000 __imag__ 008 0000 __inline 008 0000 __inline__ 150 0002 __is_abstract 151 0002 __is_aggregate 152 0002 __is_base_of 153 0002 __is_class 154 0002 __is_empty 155 0002 __is_enum 156 0002 __is_final 157 0002 __is_layout_compatible 158 0002 __is_literal_type 159 0002 __is_pointer_interconvertible_base_of 160 0002 __is_pod 161 0002 __is_polymorphic 162 0002 __is_same 162 0002 __is_same_as 163 0002 __is_standard_layout 164 0002 __is_trivial 165 0002 __is_trivially_assignable 166 0002 __is_trivially_constructible 167 0002 __is_trivially_copyable 168 0002 __is_union 072 0000 __label__ 115 0000 __null 071 0000 __real 071 0000 __real__ 012 0000 __restrict 012 0000 __restrict__ 010 0000 __signed 010 0000 __signed__ 016 0000 __thread 102 0000 __transaction_atomic 103 0000 __transaction_relaxed 104 0000 __transaction_cancel 065 0000 __typeof 065 0000 __typeof__ 169 0002 __underlying_type 009 0000 __volatile 009 0000 __volatile__ 099 020A alignas 066 020A alignof 064 0040 asm 011 0000 auto 108 0202 bool 059 0000 break 057 0000 case 116 0300 catch 044 0000 char 181 1202 char8_t 130 020A char16_t 131 020A char32_t 110 0300 class 003 0000 const 180 2202 consteval 174 020A constexpr 179 2202 constinit 132 0202 const_cast 060 0000 continue 175 020A decltype 058 0000 default 117 0202 delete 054 0000 do 046 0000 double 133 0202 dynamic_cast 052 0000 else 048 0000 enum 020 0202 explicit 021 0202 export 004 0000 extern 118 0202 false 045 0000 float 055 0000 for 018 0202 friend 062 0000 goto 051 0000 if 008 0020 inline 043 0000 int 002 0000 long 022 0202 mutable 119 0202 namespace 120 0202 new 176 020A noexcept 177 020A nullptr 122 0202 operator 112 0300 private 113 0300 protected 111 0300 public 005 0000 register 134 0202 reinterpret_cast 061 0000 return 007 0000 short 010 0000 signed 063 0000 sizeof 000 0000 static 178 020A static_assert 135 0202 static_cast 049 0000 struct 056 0000 switch 114 0202 template 123 0202 this 016 020A thread_local 124 0300 throw 125 0202 true 126 0300 try 006 0000 typedef 127 0202 typename 128 0202 typeid 065 0050 typeof 050 0000 union 001 0000 unsigned 129 0202 using 019 0202 virtual 047 0000 void 009 0000 volatile 109 0002 wchar_t 053 0000 while 170 0002 __is_assignable 171 0002 __is_constructible 172 0002 __is_nothrow_assignable 173 0002 __is_nothrow_constructible 182 0602 concept 183 0602 requires 184 8202 module 185 8202 import 186 8202 export 187 4202 co_await 188 4202 co_yield 189 4202 co_return

実行環境

GNU bash, version 5.1.16
GCC-12.2.0
GNU C Library 2.36
GNU Binutils 2.39


コード例・出力内容中の表記

・実行例中の太字表記部分は、コマンドなどの入力された文字列を示します。
・「」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。