Last Update 2023/07/27
概要
識別子使用可能文字のテスト
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)は以下のライセンスに基づくものとする。
なお、サンプルコードとしての性格上、コード内へのライセンス関連の記述は省略する。
gcc-12.2.0/gcc/c-family/c-common.h --- 63行目~278行目
enum rid
enum rid
予約語の列挙定数(C、C++、Objective-C)
gcc-12.2.0/gcc/c-family/c-common.h --- 401行目~408行目
struct c_common_resword
struct c_common_resword
予約語テーブル登録構造体
gcc-12.2.0/gcc/c-family/c-common.h --- 442行目~462行目
無効化マスク
(reswords[i].disable & mask)の結果がtrueの場合は、reswords[i]は無効
(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[]
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型変数の識別子として定義・使用するコードとして出力
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で生成されたコード
コンパイルの実行時にエラーが発生しなければ、当該キーワードは識別子として使用可能と確認される
上記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
無効化マスク | 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)の予約語リストを出力
上記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の値(整数値)、無効マスク値、予約語文字列
出力順 : 予約語の列挙定数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
GCC-12.2.0
GNU C Library 2.36
GNU Binutils 2.39
コード例・出力内容中の表記
・実行例中の太字表記部分は、コマンドなどの入力された文字列を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。