Playing with __attributes__ (一)

前言

在一些代碼中咱們常常能看見以下的一些函數修飾符:html

__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用於指定函數參數中存在打印編碼風格的參數。macos

不少屬性是平臺相關的,好比不少平臺支持interrupt,但具體使用時必須聽從特定平臺的寄存器使用規範。bootstrap

__declspec(dllimport) 就是一個常見的在Windows下用於聲明從動態庫引入函數的聲明。segmentfault

函數屬性使用__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

同理在程序結束時調用。pwa

constructor && destructor with PRIORITY

語法:__attribute__((destructor (PRIORITY)))
PRIORITY越小,優先級越高,越早調用
如:code

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)));

運行結果:orm

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,戳這裏.下期再詳述

參考閱讀

1
2

原做寫於segmentfault 連接

相關文章
相關標籤/搜索