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

テスト概要

その1
識別子として使用可能な文字に関するテスト

その2
GCC-12.2.0における実装ベースの予約語の調査

その3
各種識別子の使用例

その4
識別子のスコープ

その5
リンケージ

その6
名前空間


その1

識別子として使用可能な文字に関するテスト

sample.c
#include <stdio.h> #include <stdlib.h> int main(void) { printf("識別子使用可能文字\n"); int ABCDEFGHIJKLMNOPQRSTUVWXYZ = 12; /* 英大文字 */ int abcdefghijklmnopqrstuvwxyz = 34; /* 英小文字 */ int _ = 56; /* 下線文字 */ int a0123456789 = 78; /* 数字(先頭以外) */ int あいうえお = 90; /* マルチバイト文字(実装による) */ printf("ABCDEFGHIJKLMNOPQRSTUVWXYZ = %d\n", ABCDEFGHIJKLMNOPQRSTUVWXYZ); printf("abcdefghijklmnopqrstuvwxyz = %d\n", abcdefghijklmnopqrstuvwxyz); printf("_ = %d\n", _); printf("a0123456789 = %d\n", a0123456789); printf("あいうえお = %d\n", あいうえお); return EXIT_SUCCESS; }

実行結果
$ ./a.out 識別子使用可能文字 ABCDEFGHIJKLMNOPQRSTUVWXYZ = 12 abcdefghijklmnopqrstuvwxyz = 34 _ = 56 a0123456789 = 78 あいうえお = 90

その2

GCC-12.2.0における実装ベースの予約語の調査
(オプション未指定時のデフォルト設定(-std=gnu17)でのコンパイル時)

この項目(識別子・その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.c
GCCのC言語ファミリー全体の予約語から、(reswords[i].disable & mask)の結果がtrueとなるキーワードを、 int型変数の識別子として定義・使用するコードとして出力
#include <stdio.h> #include <stdlib.h> #include "sample.h" int main(void) { 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_CXXONLY | D_CXX11 | D_OBJC | D_CXX_OBJC | D_CXXWARN | D_CXX_CONCEPTS | D_TRANSMEM | D_CXX_CHAR8_T | D_CXX20 | D_CXX_COROUTINES | D_CXX_MODULES | D_CXX_CONCEPTS_FLAGS | D_CXX_CHAR8_T_FLAGS | D_CXX_MODULES_FLAGS | D_CXX_COROUTINES_FLAGS)) { printf("int %s = %d; ", c_common_reswords[i].word, c_common_reswords[i].rid); printf("printf(\"%s = %%d\\n\", %s);\n", c_common_reswords[i].word, c_common_reswords[i].word); } } return EXIT_SUCCESS; }

実行結果
$ gcc -Wall sample1.c $ ./a.out int __bases = 137; printf("__bases = %d\n", __bases); int __builtin_addressof = 136; printf("__builtin_addressof = %d\n", __builtin_addressof); int nonnull = 40; printf("nonnull = %d\n", nonnull); int null_resettable = 41; printf("null_resettable = %d\n", null_resettable);

sample2.c
上記sample1.cの出力内容から作成したコード
青色部はsample1.cで生成されたコード
コンパイルの実行時にエラーが発生しなければ、当該キーワードは識別子として使用可能と確認される
#include <stdio.h> #include <stdlib.h> int main(void) { int __bases = 137; printf("__bases = %d\n", __bases); int __builtin_addressof = 136; printf("__builtin_addressof = %d\n", __builtin_addressof); int __builtin_bit_cast = 149; printf("__builtin_bit_cast = %d\n", __builtin_bit_cast); int __builtin_launder = 138; printf("__builtin_launder = %d\n", __builtin_launder); int __constinit = 179; printf("__constinit = %d\n", __constinit); int __decltype = 175; printf("__decltype = %d\n", __decltype); int __direct_bases = 139; printf("__direct_bases = %d\n", __direct_bases); int __has_nothrow_assign = 140; printf("__has_nothrow_assign = %d\n", __has_nothrow_assign); int __has_nothrow_constructor = 141; printf("__has_nothrow_constructor = %d\n", __has_nothrow_constructor); int __has_nothrow_copy = 142; printf("__has_nothrow_copy = %d\n", __has_nothrow_copy); int __has_trivial_assign = 143; printf("__has_trivial_assign = %d\n", __has_trivial_assign); int __has_trivial_constructor = 144; printf("__has_trivial_constructor = %d\n", __has_trivial_constructor); int __has_trivial_copy = 145; printf("__has_trivial_copy = %d\n", __has_trivial_copy); int __has_trivial_destructor = 146; printf("__has_trivial_destructor = %d\n", __has_trivial_destructor); int __has_unique_object_representations = 147; printf("__has_unique_object_representations = %d\n", __has_unique_object_representations); int __has_virtual_destructor = 148; printf("__has_virtual_destructor = %d\n", __has_virtual_destructor); int __is_abstract = 150; printf("__is_abstract = %d\n", __is_abstract); int __is_aggregate = 151; printf("__is_aggregate = %d\n", __is_aggregate); int __is_base_of = 152; printf("__is_base_of = %d\n", __is_base_of); int __is_class = 153; printf("__is_class = %d\n", __is_class); int __is_empty = 154; printf("__is_empty = %d\n", __is_empty); int __is_enum = 155; printf("__is_enum = %d\n", __is_enum); int __is_final = 156; printf("__is_final = %d\n", __is_final); int __is_layout_compatible = 157; printf("__is_layout_compatible = %d\n", __is_layout_compatible); int __is_literal_type = 158; printf("__is_literal_type = %d\n", __is_literal_type); int __is_pointer_interconvertible_base_of = 159; printf("__is_pointer_interconvertible_base_of = %d\n", __is_pointer_interconvertible_base_of); int __is_pod = 160; printf("__is_pod = %d\n", __is_pod); int __is_polymorphic = 161; printf("__is_polymorphic = %d\n", __is_polymorphic); int __is_same = 162; printf("__is_same = %d\n", __is_same); int __is_same_as = 162; printf("__is_same_as = %d\n", __is_same_as); int __is_standard_layout = 163; printf("__is_standard_layout = %d\n", __is_standard_layout); int __is_trivial = 164; printf("__is_trivial = %d\n", __is_trivial); int __is_trivially_assignable = 165; printf("__is_trivially_assignable = %d\n", __is_trivially_assignable); int __is_trivially_constructible = 166; printf("__is_trivially_constructible = %d\n", __is_trivially_constructible); int __is_trivially_copyable = 167; printf("__is_trivially_copyable = %d\n", __is_trivially_copyable); int __is_union = 168; printf("__is_union = %d\n", __is_union); int __underlying_type = 169; printf("__underlying_type = %d\n", __underlying_type); int alignas = 99; printf("alignas = %d\n", alignas); int alignof = 66; printf("alignof = %d\n", alignof); int bool = 108; printf("bool = %d\n", bool); int catch = 116; printf("catch = %d\n", catch); int char8_t = 181; printf("char8_t = %d\n", char8_t); int char16_t = 130; printf("char16_t = %d\n", char16_t); int char32_t = 131; printf("char32_t = %d\n", char32_t); int class = 110; printf("class = %d\n", class); int consteval = 180; printf("consteval = %d\n", consteval); int constexpr = 174; printf("constexpr = %d\n", constexpr); int constinit = 179; printf("constinit = %d\n", constinit); int const_cast = 132; printf("const_cast = %d\n", const_cast); int decltype = 175; printf("decltype = %d\n", decltype); int delete = 117; printf("delete = %d\n", delete); int dynamic_cast = 133; printf("dynamic_cast = %d\n", dynamic_cast); int explicit = 20; printf("explicit = %d\n", explicit); int export = 21; printf("export = %d\n", export); int false = 118; printf("false = %d\n", false); int friend = 18; printf("friend = %d\n", friend); int mutable = 22; printf("mutable = %d\n", mutable); int namespace = 119; printf("namespace = %d\n", namespace); int new = 120; printf("new = %d\n", new); int noexcept = 176; printf("noexcept = %d\n", noexcept); int nullptr = 177; printf("nullptr = %d\n", nullptr); int operator = 122; printf("operator = %d\n", operator); int private = 112; printf("private = %d\n", private); int protected = 113; printf("protected = %d\n", protected); int public = 111; printf("public = %d\n", public); int reinterpret_cast = 134; printf("reinterpret_cast = %d\n", reinterpret_cast); int static_assert = 178; printf("static_assert = %d\n", static_assert); int static_cast = 135; printf("static_cast = %d\n", static_cast); int template = 114; printf("template = %d\n", template); int this = 123; printf("this = %d\n", this); int thread_local = 16; printf("thread_local = %d\n", thread_local); int throw = 124; printf("throw = %d\n", throw); int true = 125; printf("true = %d\n", true); int try = 126; printf("try = %d\n", try); int typename = 127; printf("typename = %d\n", typename); int typeid = 128; printf("typeid = %d\n", typeid); int using = 129; printf("using = %d\n", using); int virtual = 19; printf("virtual = %d\n", virtual); int wchar_t = 109; printf("wchar_t = %d\n", wchar_t); int __is_assignable = 170; printf("__is_assignable = %d\n", __is_assignable); int __is_constructible = 171; printf("__is_constructible = %d\n", __is_constructible); int __is_nothrow_assignable = 172; printf("__is_nothrow_assignable = %d\n", __is_nothrow_assignable); int __is_nothrow_constructible = 173; printf("__is_nothrow_constructible = %d\n", __is_nothrow_constructible); int synchronized = 192; printf("synchronized = %d\n", synchronized); int atomic_noexcept = 190; printf("atomic_noexcept = %d\n", atomic_noexcept); int atomic_cancel = 191; printf("atomic_cancel = %d\n", atomic_cancel); int atomic_commit = 102; printf("atomic_commit = %d\n", atomic_commit); int concept = 182; printf("concept = %d\n", concept); int requires = 183; printf("requires = %d\n", requires); int module = 184; printf("module = %d\n", module ); int import = 185; printf("import = %d\n", import ); /* int export = 186; printf("export = %d\n", export ); 重複回避のためコメントアウト*/ int co_await = 187; printf("co_await = %d\n", co_await); int co_yield = 188; printf("co_yield = %d\n", co_yield); int co_return = 189; printf("co_return = %d\n", co_return); int compatibility_alias = 196; printf("compatibility_alias = %d\n", compatibility_alias); int defs = 197; printf("defs = %d\n", defs); int encode = 193; printf("encode = %d\n", encode); int end = 194; printf("end = %d\n", end); int implementation = 215; printf("implementation = %d\n", implementation); int interface = 214; printf("interface = %d\n", interface); int protocol = 202; printf("protocol = %d\n", protocol); int selector = 203; printf("selector = %d\n", selector); int finally = 207; printf("finally = %d\n", finally); int optional = 209; printf("optional = %d\n", optional); int required = 210; printf("required = %d\n", required); int property = 211; printf("property = %d\n", property); int package = 201; printf("package = %d\n", package); int synthesize = 212; printf("synthesize = %d\n", synthesize); int dynamic = 213; printf("dynamic = %d\n", dynamic); int bycopy = 26; printf("bycopy = %d\n", bycopy); int byref = 27; printf("byref = %d\n", byref); int in = 23; printf("in = %d\n", in); int inout = 25; printf("inout = %d\n", inout); int oneway = 28; printf("oneway = %d\n", oneway); int out = 24; printf("out = %d\n", out); int assign = 33; printf("assign = %d\n", assign); int atomic = 36; printf("atomic = %d\n", atomic); int copy = 35; printf("copy = %d\n", copy); int getter = 29; printf("getter = %d\n", getter); int nonatomic = 37; printf("nonatomic = %d\n", nonatomic); int readonly = 31; printf("readonly = %d\n", readonly); int readwrite = 32; printf("readwrite = %d\n", readwrite); int retain = 34; printf("retain = %d\n", retain); int setter = 30; printf("setter = %d\n", setter); int null_unspecified = 38; printf("null_unspecified = %d\n", null_unspecified); int nullable = 39; printf("nullable = %d\n", nullable); int nonnull = 40; printf("nonnull = %d\n", nonnull); int null_resettable = 41; printf("null_resettable = %d\n", null_resettable); return EXIT_SUCCESS; }

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

sample3.c
上記sample2.c出力結果には含まれない、実装されているCコンパイラ(GCC)の予約語リストを出力
#include <stdio.h> #include <stdlib.h> #include "sample.h" int main(void) { 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_CXXONLY | D_CXX11 | D_OBJC | D_CXX_OBJC | D_CXXWARN | D_CXX_CONCEPTS | D_TRANSMEM | D_CXX_CHAR8_T | D_CXX20 | D_CXX_COROUTINES | D_CXX_MODULES | D_CXX_CONCEPTS_FLAGS | D_CXX_CHAR8_T_FLAGS | D_CXX_MODULES_FLAGS | D_CXX_COROUTINES_FLAGS))) { printf("%03d %02X %s\n", c_common_reswords[i].rid, c_common_reswords[i].disable, c_common_reswords[i].word); } } return EXIT_SUCCESS; }

実行結果
出力順 : 予約語の列挙定数ridの値(整数値)、無効マスク値、予約語文字列
$ gcc -Wall sample3.c $ ./a.out 099 01 _Alignas <--- 以降、GCC-12.2.0のC言語実装(オプション無しコンパイル時)に関する予約語 066 01 _Alignof 014 01 _Atomic 108 01 _Bool 015 00 _Complex 042 01 _Imaginary 085 01 _Float16 086 01 _Float32 087 01 _Float64 088 01 _Float128 089 01 _Float32x 090 01 _Float64x 091 01 _Float128x 082 01 _Decimal32 083 01 _Decimal64 084 01 _Decimal128 092 11 _Fract 093 11 _Accum 017 11 _Sat 178 01 _Static_assert 013 01 _Noreturn 100 01 _Generic 016 01 _Thread_local 105 00 __FUNCTION__ 106 00 __PRETTY_FUNCTION__ 066 00 __alignof 066 00 __alignof__ 064 00 __asm 064 00 __asm__ 067 00 __attribute 067 00 __attribute__ 094 01 __auto_type 095 01 __builtin_call_with_static_chain 073 01 __builtin_choose_expr 075 01 __builtin_complex 078 00 __builtin_convertvector 080 00 __builtin_has_attribute 081 00 __builtin_assoc_barrier 076 00 __builtin_shuffle 077 00 __builtin_shufflevector 079 01 __builtin_tgmath 121 00 __builtin_offsetof 074 01 __builtin_types_compatible_p 068 00 __builtin_va_arg 015 00 __complex 015 00 __complex__ 003 00 __const 003 00 __const__ 069 00 __extension__ 107 00 __func__ 070 00 __imag 070 00 __imag__ 008 00 __inline 008 00 __inline__ 072 00 __label__ 115 00 __null 071 00 __real 071 00 __real__ 012 00 __restrict 012 00 __restrict__ 010 00 __signed 010 00 __signed__ 016 00 __thread 102 00 __transaction_atomic 103 00 __transaction_relaxed 104 00 __transaction_cancel 065 00 __typeof 065 00 __typeof__ 009 00 __volatile 009 00 __volatile__ 096 01 __GIMPLE 097 01 __PHI 098 01 __RTL 064 40 asm 011 00 auto 059 00 break 057 00 case 044 00 char 003 00 const 060 00 continue 058 00 default 054 00 do 046 00 double 052 00 else 048 00 enum 004 00 extern 045 00 float 055 00 for 062 00 goto 051 00 if 008 20 inline 043 00 int 002 00 long 005 00 register 012 05 restrict 061 00 return 007 00 short 010 00 signed 063 00 sizeof 000 00 static 049 00 struct 056 00 switch 006 00 typedef 065 50 typeof 050 00 union 001 00 unsigned 047 00 void 009 00 volatile 053 00 while

その3

各種識別子の使用例

sample.c
#include <stdio.h> #include <stdlib.h> /* マクロ名 */ #define ID_MACRO_NAME1 123 #define ID_MACRO_NAME2 456 /* 構造体タグ名 */ struct id_struct_tag { /* 構造体メンバ名 */ int id_struct_mem; }; /* 共用体タグ名 */ union id_union_tag { /* 共用体メンバ名 */ char id_union_mem1[4]; int id_union_mem2; }; /* 列挙型タグ名 */ enum id_enum_tag { /* 列挙型メンバ名 */ id_enum_mem1, id_enum_mem2 }; /* typedef名 */ typedef struct samp_struct { int samp; } id_typedef; /* 関数名 */ int id_function(struct id_struct_tag *s, union id_union_tag *u, enum id_enum_tag en, id_typedef *t) { printf("%d\n", s->id_struct_mem); printf("%d\n", u->id_union_mem2); printf("%d\n", en); printf("%d\n", t->samp); return s->id_struct_mem; } int main(void) { /* 変数名 */ int id_var = 1; struct id_struct_tag st = {ID_MACRO_NAME1}; union id_union_tag un = {.id_union_mem1 = {0, 1, 0, 0}}; id_typedef ty = {ID_MACRO_NAME2}; id_var = id_function(&st, &un, id_enum_mem2, &ty); if (id_var != 0) { goto id_label; } return EXIT_FAILURE; /* ラベル名 */ id_label: printf("id_label\n"); return EXIT_SUCCESS; }

実行結果
$ ./a.out 123 256 1 456 id_label

その4

識別子のスコープ

sample.c
#include <stdio.h> #include <stdlib.h> /* 関数の宣言(関数プロトタイプ) 引数の識別子のスコープはプロトタイプ内のみ。省略も可能 */ void sampfunc1(const char *p_s); void sampfunc2(int id_i, const char *); /* ファイルスコープとなる変数 p_samp */ const char *p_samp = "file_scope"; void sampfunc1(const char *p_s) { /* 関数スコープ(sampfunc1)となる変数 s */ const char *s = "scope_sampfunc1"; printf("sampfunc1 --- p_s = %s : s = %s : samp_s = %s\n", p_s, s, p_samp); } void sampfunc2(int i, const char *p) { printf("sampfunc2 --- i = %d : p = %s\n", i, p); } int main(void) { /* 関数スコープ(main)となる変数 s */ const char *s = "scope_main"; sampfunc1(s); sampfunc2(2, p_samp); /* 関数スコープとなる変数 i */ int i = -1; /* for文内でのブロックスコープとなる変数 i */ for (int i=0; i < 3; i++) { if (i > 1) { /* ブロック外ラベルへのジャンプ */ goto id_label; } printf("for文ブロック内 --- i = %d\n", i); } return EXIT_FAILURE; /* ラベル(関数スコープ) */ id_label: printf("for文ブロック外 --- i = %d\n", i); printf("id_label\n"); return EXIT_SUCCESS; }

実行結果
$ ./a.out sampfunc1 --- p_s = scope_main : s = scope_sampfunc1 : samp_s = file_scope sampfunc2 --- i = 2 : p = file_scope for文ブロック内 --- i = 0 for文ブロック内 --- i = 1 for文ブロック外 --- i = -1 id_label

その5

リンケージ

sample1.c
#include <stdio.h> #include <stdlib.h> /* 外部リンケージを持つ変数 */ extern const char *p_samp1; /* 外部リンケージを持つ関数の宣言(extern無し・デフォルト) sampfunc1 */ void sampfunc1(void); /* 内部リンケージを持つ変数 */ static const char *p_samp2 = "sample1.c p_samp2 内部"; /* 外部リンケージを持つ変数 p_samp3 */ const char *p_samp3 = "sample1.c p_samp3 外部"; /* 内部リンケージを持つ関数 sampfunc2 */ static void sampfunc2(void) { printf("[1] sampfunc2 %s : %s\n", p_samp1, p_samp2); } /* 外部リンケージを持つ関数 sampfunc3 */ void sampfunc3(void) { printf("[1] sampfunc3 %s : %s\n", p_samp1, p_samp2); } int main(void) { /* リンケージ無し(関数内でextern無しで宣言) p_samp3 */ const char *p_samp3 = "sample1.c p_samp3 無し"; /* sample1.c内関数の呼び出し */ sampfunc1(); /* sample2.c内関数の呼び出し */ sampfunc2(); /* リンケージ無しのp_samp3を出力 */ printf("[1] main %s\n", p_samp3); return EXIT_SUCCESS; }
sample2.c
#include <stdio.h> #include <stdlib.h> /* 外部リンケージを持つ変数 p_samp1 */ const char *p_samp1 = "sample2.c p_samp1 外部"; /* 内部リンケージを持つ変数 p_samp2 */ static const char *p_samp2 = "sample2.c p_samp2 内部"; /* 外部リンケージを持つ変数 p_samp3 */ extern const char *p_samp3; /* 外部リンケージを持つ関数の宣言(extern付き) sampfunc3 */ extern void sampfunc3(void); /* 内部リンケージを持つ関数 sampfunc2 */ static void sampfunc2(void) { printf("[2] sampfunc2 %s : %s\n", p_samp1, p_samp2); printf("[2] sampfunc2 %s\n", p_samp3); } /* 外部リンケージを持つ関数 sampfunc1 */ void sampfunc1(void) { sampfunc2(); sampfunc3(); printf("[2] sampfunc1 %s : %s\n", p_samp1, p_samp2); }

実行結果
$ gcc -Wall sample1.c sample2.c $ ./a.out [2] sampfunc2 sample2.c p_samp1 外部 : sample2.c p_samp2 内部 [2] sampfunc2 sample1.c p_samp3 外部 [1] sampfunc3 sample2.c p_samp1 外部 : sample1.c p_samp2 内部 [2] sampfunc1 sample2.c p_samp1 外部 : sample2.c p_samp2 内部 [1] sampfunc2 sample2.c p_samp1 外部 : sample1.c p_samp2 内部 [1] main sample1.c p_samp3 無し

その6

名前空間

sample.c
異なる名前空間で同名の識別子を使用したサンプルコード
#include <stdio.h> #include <stdlib.h> /* 構造体タグ名 */ struct id_sample { /* 構造体メンバ名 */ int id_sample; }; int main(void) { /* 通常識別子名 */ struct id_sample id_sample; for (id_sample.id_sample=0; id_sample.id_sample < 3; id_sample.id_sample++) { if (id_sample.id_sample > 1) { /* ラベルへのジャンプ */ goto id_sample; } printf("for文ブロック内 --- id_sample.id_sample = %d\n", id_sample.id_sample); } return EXIT_FAILURE; /* ラベル */ id_sample: printf("ラベル : id_sample\n"); return EXIT_SUCCESS; }

実行結果
$ ./a.out for文ブロック内 --- id_sample.id_sample = 0 for文ブロック内 --- id_sample.id_sample = 1 ラベル : id_sample

実行環境

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


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

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