我是靠谱客的博主 迷人豆芽,最近开发中收集的这篇文章主要介绍C语言__attribute__,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

    • 一 介绍
    • 二 语法
    • 三 函数属性
      • 1 format
      • 2 noreturn
      • 3 const
      • 4 noinline
      • 5 always_inline
      • 6 pure
      • 7 nothrow
      • 8 sentinel
      • 9 format_arg
      • 10 no_instrument_function
      • 11 section
      • 12 constructor
      • 13 destructor
      • 14 used
      • 15 unused
      • 16 deprecated
      • 17 weak
      • 18 malloc
      • a19 lias
      • 20 warn_unused_result
      • 21 nonnull
    • 四 类型属性(Type Attributes)
      • 1 aligned
      • 2 packed
      • 3 transparent_union
      • 4 deprecated
      • 5 may_alias
      • 6 constructor_destructor
    • 五 变量属性(Variable Attribute)
    • 六 Clang特有的
    • 七 demo

一 介绍

  GNU C的一大特色就是 __attribute__ 机制。可以设置函数属性(Function Attribute)变量属性(Variable Attribute)类型属性(Type Attribute)
  关键字 __attribute__ 也可以对结构体(struct)或共用体(union)进行属性设置。大致有六个参数值可以被设定,即:alignedpackedtransparent_unionunuseddeprecatedmay_alias

二 语法

  __attribute__ 语法格式为:__attribute__((attribute-list))
  在使用 __attribute__ 参数时,你也可以在参数的前后都加上 __ (两个下划线),例如,使用 __aligned__ 而不是 aligned,这样,你就可以在相应的头文件里使用它而不用关心头文件里是否有重名的宏定义。

三 函数属性

  函数属性可以帮助开发者把一些特性添加到函数声明中,从而可以使编译器在错误检查方面的功能更强大。__attribute__ 机制也很容易同非GNU应用程序做到兼容之功效。GNU CC需要使用–Wall编译器来击活该功能,这是控制警告信息的一个很好的方式。

1 format

  作用:__attribute__ 属性可以给被声明的函数加上类似printf或者scanf的特征,它可以使编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配。该功能十分有用,尤其是处理一些很难发现的bug。
  语法:format(archetype, string-index, first-to-check)
  format属性告诉编译器,按照printfscanfstrftimestrfmon 的参数表格式规则对该函数的参数进行检查。archetype 指定是哪种风格;string-index 指定传入函数的第几个参数是格式化字符串;first-to-check 指定从函数的第几个参数开始按上述规则进行检查。
  具体使用:__attribute__((format(printf,m,n)))__attribute__((format(scanf,m,n)))
  其中参数m与n的含义为:m:第几个参数为格式化字符串(format string);n:参数集合中的第一个,即参数“…”里的第一个参数在函数参数总数排在第几,注意,有时函数参数里还有“隐身”的。

//m=1;n=2
extern void myprint(const char *format,...) __attribute__((format(printf,1,2)));
//m=2;n=3
extern void myprint(int l,const char *format,...) __attribute__((format(printf,2,3)));
//需要特别注意的是,如果myprint是一个函数的成员函数,那么m和n的值可有点“悬乎”了,例如:
//m=3;n=4
extern void myprint(int l,const char *format,...) __attribute__((format(printf,3,4)));
//其原因是,类成员函数的第一个参数实际上一个“隐身”的“this”指针。
//format-myprintf.c
#include <stdio.h>
#include <stdarg.h>

#ifdef ON
	//告诉编译器以printf的方式去检查该函数
	extern void myprint(const char *format,...) __attribute__((format(printf,1,2)));
#else
	extern void myprint(const char *format,...);
#endif

void test()
{
    myprint("i=%dn",6);
    myprint("i=%sn",6);
    myprint("i=%sn","abc");
    myprint("%s,%d,%dn",1,2);
}

//gcc -Wall format-myprintf.c -D ON
//gcc -Wall format-myprintf.c 
int main()
{
    test();
    return 0;
}

  注意:默认情况下,编译器是能识别类似printf的“标准”库函数。

2 noreturn

  该属性通知编译器函数从不返回值,当遇到类似函数需要返回值而却不可能运行到返回值处就已经退出来的情况,该属性可以避免出现错误信息。C库函数中的 abort()exit() 的声明格式就采用了这种格式,如下所示:
extern void exit(int) __attribute__((noreturn));
extern void abort(void) __attribute__((noreturn));

//noreturn.c
#include <stdio.h>
#include <stdarg.h>

#ifdef ON
    extern void myexit() __attribute__((noreturn));
#else
    extern void myexit() ;
#endif

int test(int n)
{
    if ( n > 0 )
    {
        myexit();
        /* 程序不可能到达这里*/
    }
    else
        return 0;
}
//https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html
//__attribute__ 告诉编译器做额外的事情。

//编译对比
//gcc -Wall noreturn.c -D ON
//gcc -Wall noreturn.c
int main()
{
    test(3);
    return 0;
}

3 const

  该属性只能用于带有数值类型参数的函数上。当重复调用带有数值参数的函数时,由于返回值是相同的,所以此时编译器可以进行优化处理,除第一次需要运算外,其它只需要返回第一次的结果就可以了,进而可以提高效率。该属性主要适用于没有静态状态(static state)和副作用的一些函数,并且返回值仅仅依赖输入的参数。

//const.c
#include <stdio.h>
#include <stdarg.h>

#ifdef ON
    extern int square(int n) __attribute__((const));
#else
    extern int square(int n);
#endif
//编译对比
//gcc -Wall const.c -D ON
//gcc -Wall const.c
int main()
{
    int total=0;
    int i=0;
    for (i = 0; i < 100; i++ )
    {
            total += square(5) + i;
    }
    printf("total=%dn",total);
    return 0;
}

4 noinline

5 always_inline

6 pure

7 nothrow

8 sentinel

9 format_arg

10 no_instrument_function

11 section

12 constructor

13 destructor

14 used

15 unused

16 deprecated

17 weak

18 malloc

a19 lias

20 warn_unused_result

21 nonnull

四 类型属性(Type Attributes)

1 aligned

//aligned.c
#include <stdio.h>
#include <stdarg.h>

#ifdef ON
//关键字__attribute__也可以对结构体(struct)或共用体(union)进行属性设置。大致有六个参数值可以被设定,
//即:aligned, packed, transparent_union, unused, deprecated 和 may_alias。
struct p
{
    int a;
    char b;
    char c;
}__attribute__((aligned(4))) pp;
struct q
{
    int a;
    char b;
    struct p qn;
    char c;
}__attribute__((aligned(8))) qq; 
#else
struct p
{
    int a;
    char b;
    char c;
} pp;

struct q
{
    int a;
    char b;
    struct p qn;
    char c;
} qq;
#endif

//__attribute__修饰变量属性(Variable Attribute)
struct test
{
    char a;
    int x[2] __attribute__ ((packed));
};

//gcc -Wall aligned.c -D ON -o a2
//gcc -Wall aligned.c -o a1
int main()
{
	printf("sizeof(int)=%d,sizeof(short)=%d.sizeof(char)=%dn",sizeof(int),sizeof(short),sizeof(char));
    printf("pp=%d,qq=%d n", sizeof(pp),sizeof(qq));
    return 0;
}

2 packed

3 transparent_union

4 deprecated

5 may_alias

6 constructor_destructor

//constructor_destructor.c
#include <stdio.h>
#include <stdarg.h>

#ifdef ON
static void start(void) __attribute__ ((constructor));
static void stop(void) __attribute__ ((destructor));
#else
static void start(void);
static void stop(void);
#endif
void start(void)
{
    printf("hello world!n");
}
void stop(void)
{
    printf("goodbye world!n");
}
//编译运行对比
//gcc -Wall noreturn.c -D ON
//gcc -Wall noreturn.c
int main(int argc, char *argv[])
{
    printf("start == %pn", start);
    printf("stop == %pn", stop);
    return 0;
}

五 变量属性(Variable Attribute)

六 Clang特有的

  • availability
  • overloadable

七 demo

#include <stdio.h>
#include <stdarg.h>
#ifdef ON
extern "C" int pthread_create (pthread_t*,
                const pthread_attr_t*,
                void* (*)(void*),
                void*) __attribute__ ((weak));
extern "C" int pthread_mutex_init (pthread_mutex_t*,
                    const pthread_mutexattr_t*) __attribute__ ((weak));
extern "C" int pthread_mutex_lock (pthread_mutex_t*) __attribute__ ((weak));
extern "C" int pthread_mutex_unlock (pthread_mutex_t*) __attribute__ ((weak));
extern "C" int pthread_mutex_destroy (pthread_mutex_t*) __attribute__ ((weak));
#else
extern "C" int pthread_create (pthread_t*,
                const pthread_attr_t*,
                void* (*)(void*),
                void*);
extern "C" int pthread_mutex_init (pthread_mutex_t*,
                    const pthread_mutexattr_t*);
extern "C" int pthread_mutex_lock (pthread_mutex_t*);
extern "C" int pthread_mutex_unlock (pthread_mutex_t*);
extern "C" int pthread_mutex_destroy (pthread_mutex_t*);
#endif
#define __init         __attribute__ ((__section__ (".text.init")))
#define __exit          __attribute__ ((unused, __section__(".text.exit")))
#define __initdata      __attribute__ ((__section__ (".data.init")))
#define __exitdata      __attribute__ ((unused, __section__ (".data.exit")))
#define __initsetup     __attribute__ ((unused,__section__ (".setup.init")))
#define __init_call     __attribute__ ((unused,__section__ (".initcall.init")))
#define __exit_call     __attribute__ ((unused,__section__ (".exitcall.exit")))
extern void foobar (void) __attribute__ ((section ("bar")));
void add(int a,int b) __attribute__ ((visibility ("protected")));
void sub(int a,int b) __attribute__ ((visibility ("hidden")));
//关键字__attribute__ 也可以对结构体(struct )或共用体(union )进行属性设置。大致有六个参数值可以被设定,
//即:aligned, packed, transparent_union, unused, deprecated 和 may_alias 。
struct STudent{
    int age;
    char name[10] __attribute__ ((aligned(8)));
};
//https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html#Function-Attributes
int old_fn () __attribute__ ((deprecated));
void f () __attribute__ ((weak, alias ("__f")));
void mul() __attribute__ ((dllexport));
void mul2() __attribute__ ((dllimport));
extern char * my_dgettext (char *my_domain, const char *my_format)  __attribute__ ((format_arg (2)));
void f2 () __attribute__ ((interrupt ("IRQ")));
//Use naked attribute on the ARM, AVR, C4x and IP2K ports to indicate that the specified function does not need prologue/
//epilogue sequences generated by the compiler.It is up to the programmer to provide these sequences.
void mydiv() __attribute__ ((naked)); 
void mydiv2() __attribute__ ((noinline));

__attribute__ ((noinline,__annotate__(("nofcf"))))
__attribute__ ((noinline,__annotate__(("nocxf"))))
__attribute__ ((noinline,__annotate__(("nosac")))) void demo();

//编译对比
//gcc -Wall weak.c -D ON
//gcc -Wall weak.c
int main()
{
    return 0;
}

https://blog.csdn.net/weixin_33770878/article/details/92129273

最后

以上就是迷人豆芽为你收集整理的C语言__attribute__的全部内容,希望文章能够帮你解决C语言__attribute__所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部