gnu C言語_attribute__さぎょう
attributeについて
linuxのソースコードを見ていると、dl_など、関連するものによく出会うかもしれません.Openの関数の中:
ここのinternal_functionはattributeの応用であり、その具体的なフォーマットは以下の通りである.
attributeは、その名の通り、関数(変数や構造体)のいくつかの属性を説明し、コンパイラにより多くの情報を提供します.ここでは、一般的なattributeの使い方を説明します.
に注意
gnu ccは-Wallでこのオプションをアクティブにする必要があります
使用法
1フォーマット判定format
説明:すなわち、フォーマット文字列に従ってパラメータの正当性を判断し、法則コンパイラがwarningの具体的なフォーマットを与える場合:attribute(format(type,string_index,first_to_check))解釈:typeはscanfまたはprintfを記入し、scanfまたはprintfで検出することを表す.string_indexはフォーマット文字列が関数のいくつかのパラメータであることを示し、最後にfirst_to_checkは、チェックするパラメータが関数の位置にある例を示します.
2関数は呼び出し元noreturnに返されません
説明:この関数は呼び出し元に戻る必要がないことを示し、不要な最適化の具体的なフォーマットを避ける:attribute(noreturn))の例:
3 const attribute
説明:この属性は主に静的状態と副作用のない関数で使用され、その戻り値は主に入力値に依存し、数値タイプの関数のみで使用でき、ポインタタイプのパラメータを持つ関数では使用できません.具体的なフォーマット:attribute(const))の例:
4 no_instrument_function
説明:この属性はgccのコンパイルオプション、-finstumat-functionに関連するため、説明が複雑である.このパラメータを追加すると、コンパイル時にinstrumentation呼び出しが生成されます.すなわち、1つの関数のエントリの後と、エクスポートの前に2つの関数が呼び出されます.それぞれ:
Instrumentation呼び出しを生成する必要がない関数は、profile関数自体、高優先度の割り込みルーチン、profilingの正常な呼び出しを保証できない関数などの典型的な使用方法で、この属性を使用して明記されます.具体的なフォーマット:attribute(no_instrument_function))の例:
コンパイルコマンド:
出力結果:(64ビットシステムです)
5 constructor/destructorプロパティ
説明:主に関数の初期化などに用いられ、constructor属性が宣言されている場合はmain関数の前に実行され、destructor属性が宣言されている場合はmain関数の実行後、またはexitが呼び出されて自動的に実行されます.具体的なフォーマット:attribute(constructor)attribute(destructor)の例:
コンパイルオプション:
実行結果:
6変数属性
説明:前に説明したすべての設定は、関数を設定します.ここでは、関数を設定するだけでなく、変数と構造体を属性設定することもできます.共通変数のプロパティ: alignedは、整列フォーマット: packed、最小整列方式を使用します. ここではリストしません.より多くの変数プロパティを参照してください.
7タイプ属性
説明:変数属性が変数に対する属性宣言のように、タイプ属性はタイプに対する属性宣言です.主にstructとunionに対して属性宣言を行い、ここでは後述しないが、第6点と比較して類似しており、より多くのタイプの属性はこれを参照してください.
tips attributeのプロパティは、マクロの重複を回避するために、前後に二重下線を付けることができます. は、 のような複数のattributeを書くこともできる.
linuxのソースコードを見ていると、dl_など、関連するものによく出会うかもしれません.Openの関数の中:
void* internal_function
_dl_open (const char *file, int mode, const void *caller)
{
struct dl_open_args args;
__rtld_lock_lock_recursive (GL(dl_load_lock));
args.file = file;
args.mode = mode;
args.caller = caller;
args.map = NULL;
dl_open_worker(&args);
__rtld_lock_unlock_recursive (GL(dl_load_lock));
}
ここのinternal_functionはattributeの応用であり、その具体的なフォーマットは以下の通りである.
#define internal_function __attribute__ ((regparm (3), stdcall))
attributeは、その名の通り、関数(変数や構造体)のいくつかの属性を説明し、コンパイラにより多くの情報を提供します.ここでは、一般的なattributeの使い方を説明します.
に注意
gnu ccは-Wallでこのオプションをアクティブにする必要があります
使用法
1フォーマット判定format
説明:すなわち、フォーマット文字列に従ってパラメータの正当性を判断し、法則コンパイラがwarningの具体的なフォーマットを与える場合:attribute(format(type,string_index,first_to_check))解釈:typeはscanfまたはprintfを記入し、scanfまたはprintfで検出することを表す.string_indexはフォーマット文字列が関数のいくつかのパラメータであることを示し、最後にfirst_to_checkは、チェックするパラメータが関数の位置にある例を示します.
void myPrint(const char* format_string, ...)
__attribute__(format(printf, 1, 2));//format_string , ...
// , , format(printf, 1, 2)
// string_index = 1, first_to_check = 2
2関数は呼び出し元noreturnに返されません
説明:この関数は呼び出し元に戻る必要がないことを示し、不要な最適化の具体的なフォーマットを避ける:attribute(noreturn))の例:
void myExit() __attribute__((noreturn));
3 const attribute
説明:この属性は主に静的状態と副作用のない関数で使用され、その戻り値は主に入力値に依存し、数値タイプの関数のみで使用でき、ポインタタイプのパラメータを持つ関数では使用できません.具体的なフォーマット:attribute(const))の例:
void intSqrt(int x)__attribute__((const))
// sqrt x , ,const
// , , ,
4 no_instrument_function
説明:この属性はgccのコンパイルオプション、-finstumat-functionに関連するため、説明が複雑である.このパラメータを追加すると、コンパイル時にinstrumentation呼び出しが生成されます.すなわち、1つの関数のエントリの後と、エクスポートの前に2つの関数が呼び出されます.それぞれ:
void __cyg_profile_func_enter(void *this_fn, void *call_site);
void __cyg_profile_func_exit(void *this_fn, void *call_site);
//profile
Instrumentation呼び出しを生成する必要がない関数は、profile関数自体、高優先度の割り込みルーチン、profilingの正常な呼び出しを保証できない関数などの典型的な使用方法で、この属性を使用して明記されます.具体的なフォーマット:attribute(no_instrument_function))の例:
//test.c
#include
void __cyg_profile_func_enter(void *, void *)
__attribute__((no_instrument_function));
void __cyg_profile_func_exit(void *, void *)
__attribute__((no_instrument_function));
void __cyg_profile_func_exit(void *this_fn, void *call_site)
{
printf("this_func: %p call_addr: %p
", this_fn, call_site);
}
void __cyg_profile_func_enter(void *this_fn, void *call_site)
{
printf("this_func: %p call_addr: %p
", this_fn, call_site);
}
int main()
{
printf("hey, everybody!
");
return 0;
}
コンパイルコマンド:
gcc -o test test.c -finstrument-functions
出力結果:(64ビットシステムです)
this_func: 0x400645 call_addr: 0x7feebbbd8f45
hey, everybody!
this_func: 0x400645 call_addr: 0x7feebbbd8f45
5 constructor/destructorプロパティ
説明:主に関数の初期化などに用いられ、constructor属性が宣言されている場合はmain関数の前に実行され、destructor属性が宣言されている場合はmain関数の実行後、またはexitが呼び出されて自動的に実行されます.具体的なフォーマット:attribute(constructor)attribute(destructor)の例:
//test.c
#include
void constructor_func()
__attribute__((constructor));
void destructor_func()
__attribute__((destructor));
void constructor_func()
{
printf("I am a constructor :)
");
}
void destructor_func()
{
printf("I am a destructor :)
");
}
int main()
{
printf("I am main, I did nothing! :(
");
return 0;
}
コンパイルオプション:
gcc -o test test.c
実行結果:
I am a constructor :)
I am main, I did nothing! :(
I am a destructor :)
6変数属性
説明:前に説明したすべての設定は、関数を設定します.ここでは、関数を設定するだけでなく、変数と構造体を属性設定することもできます.共通変数のプロパティ:
int x[3] __attrubute__((aligned(16)))
、すなわち16バイト整列を示す.(オブジェクトのスペースを増やす)int x[3] __attribute__((packed))
(オブジェクトの占有スペースを減らす)...7タイプ属性
説明:変数属性が変数に対する属性宣言のように、タイプ属性はタイプに対する属性宣言です.主にstructとunionに対して属性宣言を行い、ここでは後述しないが、第6点と比較して類似しており、より多くのタイプの属性はこれを参照してください.
tips
__attrubute__((noreturn, format(printf, 1, 2)))
のような複数の属性を1つのattributeで示すことができ、__attribute__((noreturn)) __attribute__((format(printf, 1, 2)))