前言
在一些代码中我们经常能看见如下的一些函数修饰符:
__attribute__((constructor)) static void foo(void) {
//...
}
void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7)));
起源
GNU C中,我们可以使用函数属性(Function attribute
)为我们的函数定义特定的编译器优化、编译器检查、内存管理、代码生成、调用返回转换。
比如:noreturn
用于指定该函数没有返回值。format
用于指定函数参数中存在打印编码风格的参数。
很多属性是平台相关的,比如很多平台支持interrupt
,但具体使用时必须遵从特定平台的寄存器使用规范。
__declspec(dllimport)
就是一个常见的在Windows下用于声明从动态库引入函数的声明。
函数属性使用__attribute__
作为声明关键字,其后用双括号(())
指定一个特定的属性,使用逗号,
间隔多个属性。具体可参见Attribute Syntax
常用的函数属性
constructor
其修饰的函数将在装载Binary的时候调用,在macos 的call stack如下:
frame #1: 0x00007fff5fc12d0b dyld`ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) + 265
frame #2: 0x00007fff5fc12e98 dyld`ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 40
frame #3: 0x00007fff5fc0f891 dyld`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 305
frame #4: 0x00007fff5fc0f718 dyld`ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 138
frame #5: 0x00007fff5fc0f989 dyld`ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 75
frame #6: 0x00007fff5fc02245 dyld`dyld::initializeMainExecutable() + 187
frame #7: 0x00007fff5fc05c19 dyld`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 2669
frame #8: 0x00007fff5fc01276 dyld`dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*) + 512
frame #9: 0x00007fff5fc01036 dyld`_dyld_start + 54
多个constructor函数调用顺序由声明顺序决定
destructor
同理在程序结束时调用。
constructor && destructor with PRIORITY
语法:__attribute__((destructor (PRIORITY)))
PRIORITY
越小,优先级越高,越早调用
如:
void begin_0 (void) __attribute__((constructor (101)));
void end_0 (void) __attribute__((destructor (101)));
void begin_1 (void) __attribute__((constructor (102)));
void end_1 (void) __attribute__((destructor (102)));
void begin_2 (void) __attribute__((constructor (103)));
void end_2 (void) __attribute__((destructor (103)));
运行结果:
begin_0 ()
begin_1 ()
begin_2 ()
end_2 ()
end_1 ()
end_0 ()
returns_nonnull
告知编译器返回值绝不为NULL
alias ("target")
为函数定义别名
其他
除了函数属性(Function Attributes
)还有 Variable Attributes
, Type Attributes
, Label Attributes
, Enumerator Attributes
等.
Clang对iOS有专用的attributes,戳这里.下期再详述
参考阅读
原作写于segmentfault 链接