Playing with __attributes__ (一)
2015-12-17 15:28
453 查看
前言
在一些代码中我们经常能看见如下的一些函数修饰符:__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
告知编译器返回值绝不为NULLalias (“target”)
为函数定义别名其他
除了函数属性(Function Attributes)还有
Variable Attributes,
Type Attributes,
Label Attributes,
Enumerator Attributes等.
Clang对iOS有专用的attributes,戳这里.下期再详述
参考阅读
12
原作写于segmentfault 链接
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- Windows Clang开发环境备忘
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 讲解iOS开发中基本的定位功能实现
- js判断客户端是iOS还是Android等移动终端的方法
- IOS开发环境windows化攻略
- 浅析iOS应用开发中线程间的通信与线程安全问题
- 检测iOS设备是否越狱的方法
- .net平台推送ios消息的实现方法
- 探讨Android与iOS,我们将何去何从?
- Android、iOS和Windows Phone中的推送技术详解
- IOS 改变键盘颜色代码
- 举例详解iOS开发过程中的沙盒机制与文件
- Android和IOS的浏览器中检测是否安装某个客户端的方法
- 分享一个iOS下实现基本绘画板功能的简单方法