gcc attribute weak&alias応用

3584 ワード

1 gcc attribute weak&alias応用
alias ("target")
The alias attribute causesthe declaration to be emitted as an alias for another symbol, which must bespecified. For instance,
         void __f () {/* Do something. */; }
         void f () __attribute__ ((weak, alias ("__f")));
defines ‘f’ to be a weakalias for ‘__f’. In C++, the mangled name for the target must be used. It is an error if‘__f’ is not definedin the same translation unit.
Not all targetmachines support this attribute. 
このGCC公式ドキュメントからの説明は、gccのaliasとweak attributeについて話しています.
1.1        gcc weak attribute
具体的な文法は、一般的なgcc属性とほぼ同じで、__を使う必要があります.attribtes__(weak))というフォーマットです.例を挙げて説明します.
1 weak_symbol.cこのファイルにcommonが宣言されています.print関数、およびこの関数を__と宣言attribute__((weak));この関数の定義も表示されます.
//weak_symbol.c
#include 
voidcommon_print(const char *s) __attribute__((weak));// weak  
voidcommon_print(const char *s)
{
    printf("common_print : %s
",s); }

2 strong_symbol.cこのファイルはcommonも定義されています.print関数は、この関数が2つの異なるcファイルで宣言、定義されたプロトタイプが同じであることに注意してください.
//strong_symbol.c
#include
 
voidcommon_print(const char *s) //  weak  
{
    printf("application common_print : %s
",s); } int main(intargc, char *argv[]) { common_print("I want to test gcc weakattribute"); return 0; }

3接続されたcファイルをコンパイルし、実行した結果は以下の通りです.
root@VM-Ubuntu203001:/home/test/gcc_test#./test_weak
applicationcommon_print : I want to test gcc weak attribute
 
分析:
1)まず,同じプロトタイプの2つの関数は,異なるcファイルでさえ定義されており,この2つのcファイルをコンパイル,接続しても誤りはない.なぜなら、gccにはstrong symbolとweak symbolの概念があるからだ.デフォルトの関数定義はstrong symbolで、同じstrong symbolが2つ接続されているため、「symbol繰返し定義」のエラーが発生するに違いありません.
しかし、ここではweak_symbol.cのcommon_printはweakプロパティを追加し、gccを再選択するときにstrong symbolを優先します.
2)次に、例のプログラム実行の結果からstrong_symbol.cのcommon_print関数.もし私たちがstrong_symbol.cではcommon_は提供されませんprint関数の実装ではweakが呼び出されますsymbol.cの実装.
3)以上から,c音声でapiライブラリを提供する場合,これらのapiをweak属性として宣言することができ,default実装を提供することができることを想像できる.ユーザーが自分でカスタマイズしようとすると、簡単に実現できます.glibcの多くのapiはこのように設計されています.
1.2 gcc weak&alias attribute配合応用シーン
同じように、まず例を見てみましょう.
1 weak_symbol.cには1つの__が提供されているlib_print関数の実装、print_の宣言aとprint_b 2つの関数ですが、上と通じないのは、この2つの関数が__増加したことです.attribute__((weak,alias("_lib_print"))熟知、すなわちprint_aとprint_bはすべて_lib_printの別名(alias).
//weak_symbol.c
#include 
 
void __lib_print(const char *s)
{
   printf("__lib_print : %s
", s); } void print_a(const char *s) __attribute__((weak, alias("__lib_print"))); void print_b(const char *s) __attribute__((weak, alias("__lib_print")));
strong_symbol.cでは
print_b実装を再提供し、
print_aデフォルトのままです.
//strong_symbol.c
#include 
 
void print_b(const char *s)
{
   printf("application print_b : %s
", s); } int main(int argc, char *argv[]) { print_a("I want to test weak&&alias"); print_b("I want to test weak&&alias"); return 0; }
3は、接続されたcファイルをコンパイルし、実行された結果は以下の通りである.
root@VM-Ubuntu203001:/hometest/gcc_test#./test_weak
__lib_print : I want to testweak&&alias
application print_b : I want to testweak&&alias
解析:実行結果からprint_a実行はweak_symbol.cの_lib_printの実装.print_bはstrong_を実行するsymbol.cのprint_b実現.この実行結果は,alias属性が1つの関数に多くの異なる別名を提供できることを説明する必要があると推測すべきである.このように、apiライブラリを提供する場合、複数のapiが同じdefault実装を持っている場合、aliasメカニズムによってdefault実装を提供することができる.