GCC-__attribute__()(一)属性机制
生活随笔
收集整理的這篇文章主要介紹了
GCC-__attribute__()(一)属性机制
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
簡介
__attribute__((option))是編譯器對C語言的擴(kuò)展,可以設(shè)置特定的函數(shù)、變量和類型的相關(guān)屬性。
使用場景
主要用于優(yōu)化代碼,保證編碼正確,優(yōu)化程序邏輯,優(yōu)化存儲格式等,正常簡單的項目都沒必要使用。
屬性列表(常用)
| constructor | F | 使被修飾的函數(shù)在main函數(shù)前被執(zhí)行 | ? |
| destructor | F | 使被修飾的函數(shù)在main函數(shù)結(jié)束后被執(zhí)行 | ? |
| format | F | 告訴編譯器,按照printf, scanf, strftime或strfmon的參數(shù)表格式規(guī)則對該函數(shù)的參數(shù)進(jìn)行檢查 | ? |
| noreturn | F | 表示這個函數(shù)沒有返回值也不能有返回值 | |
| const | F | 表示一個方法的返回值只由參數(shù)決定,如果參數(shù)不變的話,就不再調(diào)用此函數(shù),直接返回值 | ? |
| weak | F | 弱函數(shù),如果同名函數(shù)在其他地方被定義將使用其他地方的函數(shù),當(dāng)其他地方?jīng)]有定義才使用該函數(shù) | ? |
| warn_unused_result | F | 表明函數(shù)返回值必須被接收或使用,否則將編譯報錯 | 建議修飾所有返回動態(tài)內(nèi)存地址和如果執(zhí)行錯誤將導(dǎo)致后續(xù)流程執(zhí)行并返回錯誤碼的函數(shù) |
| cleanup() | V | 用于修飾變量,在變量作用域結(jié)束后調(diào)用指定函數(shù) | ? |
| always_inline | F | 保證代碼是內(nèi)聯(lián)的,強制內(nèi)聯(lián) | 不一定有效,具體還是得看編譯器 |
| section("name") | FV | 在編譯時將被修飾的函數(shù)或數(shù)據(jù)放入指定名為"name"對應(yīng)的段中 | 需要修改鏈接腳本才能生效 |
| aligned(n) | VT | 格式化對齊,強制編譯器為結(jié)構(gòu)體分配空間時采用規(guī)定位對齊,不指定數(shù)字時,編譯器自動選擇對目標(biāo)機器最優(yōu)方式 | ? |
| nothrow | F | 屬性告訴編譯器函數(shù)不能拋出異常(當(dāng)代碼會被C++調(diào)用時才使用) | ? |
| packed | VT | 告訴編譯器取消結(jié)構(gòu)在編譯過程中的優(yōu)化對齊, 按照實際占用字節(jié)數(shù)進(jìn)行對齊 | ? |
| pure | F | 函數(shù)除返回值外,不會通過其它(如全局變量、指針)對函數(shù)外部產(chǎn)生任何影響。 | ? |
| nonull(n) | ‘F’ | 函數(shù)第n個參數(shù)不能為NULL | 多個參數(shù)時使用逗號隔開 |
| … |
注:
如果不確定屬性是否支持或存在,可以使用關(guān)鍵宏__has_attribute,進(jìn)行判定。
#ifndef __has_attribute /*!< 判斷一下是否支持 __has_attribute */ #warning Unsupport __has_attribute #define __has_attribute(x) 0 #endif #if __has_attribute(visibility) /*!< 判斷一下是否支持 visibility*/ #define ATTR_EXTERNAL_API __attribute__((visibility("default"))) #define ATTR_LOCAL_API __attribute__((visibility("hidden"))) #else #error Unsupport visibility. #endif使用格式
標(biāo)準(zhǔn)的使用位置是放置在聲明的尾部的;之前。
多個屬性使用,隔開,如int hello(void) __attribute__((noreturn,constructor));
使用示例
#include <stdio.h> /*** @brief 定義一個函數(shù)init,使用屬性`constructor`修飾,使該函數(shù)在main函數(shù)執(zhí)行前執(zhí)行.*/ static void init(void) __attribute__((constructor)); /*** @brief 定義一個函數(shù)deinit,使用屬性`constructor`修飾,使該函數(shù)在main函數(shù)執(zhí)行后執(zhí)行.*/ static void deinit(void) __attribute__((destructor));int main(int argc, char **argv) {printf("main\n");return 0; }static void init(void) {printf("init\n"); }static void deinit(void) {printf("deinit\n"); }然后正常編譯(ubuntu 16.04x64)
gcc -o test test.c
執(zhí)行程序:
root@seven: ~/projects/test# ./test init main deinit root@seven: ~/projects/test#函數(shù)init在main之前執(zhí)行,函數(shù)deinit在main之后執(zhí)行。
總結(jié)
以上是生活随笔為你收集整理的GCC-__attribute__()(一)属性机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 班级优化大师如何添加学生名单
- 下一篇: 洋葱学院(怎样评价洋葱数学这样一个应用)