__attribute__

__attribute__是GCC启用的很有用的编译器指令
类似于ISO C的#pragma
在LLVM下得到了扩充

常用的有:

  • __attribute__((const)):用于函数式编程,所修饰的函数只会计算一次,后续调用都返回第一次计算出的返回值
  • __attribute__((overloading)):用于C函数的可重载化
  • __attribute__((availability)):这个大家在OC中应该有所见闻,用来标记所修饰符号适用的系统版本
  • __attribute__((unused)):这个在调试的时候应该会用过,类似于__unused修饰符,假如修饰的符号未被后续程序调用,也不会产生警告
  • __attribute__((nonnull)):类似于OC中的nonnull修饰符和Swift中的"!"修饰符,这个参数存空值会发出警告
  • __attribute__((format, m, n)):用于使用printf,scanf等C语言可变参数函数模型。意味着第m个参数是格式字符串,第n个参数开始是变参
  • __attribute__((cleanup)):类似于Swift中的defer关键字,其修饰的函数会在当前函数作用域退出时执行
  • __attribute__((always_inline)):
    一般情况下,如果不做编译优化的话函数是不会被自动内联的。对于已经声明为内联的函数,这个修饰符让编译器忽略其他限制条件把该函数内联处理。一旦无法执行内联操作,编译器便会报错。但是假如这个函数被间接调用(例如使用函数指针),编译器能不能把它内联就不确定了。这个时候若无法内联,编译器也不一定会报错。
  • __attribute__((noreturn)):这个修饰的函数类似于Swift中的返回值类型为Never的函数。它们没有返回值,往往会一直运行下去或就此退出程序。例如C函数库中的abort(),exit(),还有AFNetworking中也有如下代码
+ (void) __attribute__((noreturn)) networkRequestThreadEntryPoint:(id)__unused object {
    do {
        @autoreleasepool {
            [[NSRunLoop currentRunLoop] run];
        }
    } while (YES);
}

乃是用于开启一个新的NSThread,内驻一个NSRunLoop循环处理网络请求。

  • __attribute__((weak)):
    这就和OC/Swift中的弱引用类似,避免程序因为引用一个不存在的外部符号(就像extern xxx)而崩溃。同时,当外部有相同的强引用符号将使用外部符号,也就是为外部符号提供了一个override的途径。

  • __attribute__ ((visibility ("visibility_type")))
    visibility属性是在ELF(Executable & Linkable Format,是二进制文件的存储格式和布局,一般是基于GCC的Linux系统使用的格式;Darwin也就是苹果内核使用的是Mach-O格式)中定义的符号可见性,可以以此确定不同域之间是否能够引用指定符号。

void __attribute__ ((visibility ("protected")))
f () { /* Do something. */; }
int i __attribute__ ((visibility ("hidden")));

一般有如下四个visibility_type:

  • default
    默认的visibility,可override别的可能改变符号可见性的attribute选项。一般加入了动态符号表中,可被其他模块看到,可以被相同的符号override。
  • hidden
    hidden修饰的符号不会放进ELF的动态符号表(Dynamic Symbol Table, 用于ELF/Mach-O形式的动态链接库(PSO)声明可被外部引用的符号)中,这样别的module就不能直接引用该符号,但是可以通过函数指针的传递间接引用。
  • internal
    internal和hidden基本是一样的,唯一的区别是它连间接引用都不允许,只能“自给自足”。
  • protected
    protected修饰的符号是可以放入ELF的动态符号表的。但是别的module的符号不能override本module的相同符号。这样引用的首先是本module的符号。

Reference

Declaring Attributes of Functions

你可能感兴趣的:(__attribute__)