GCC/G++扩展特性

来源:互联网 发布:冒险岛数据库中心 编辑:程序博客网 时间:2024/06/06 02:16

GCC/G++扩展特性

标签用作值

void *ptr;

/* ... */

ptr = &&foo;

goto *ptr;

static void *array[] = { &&foo, &&bar,&&hack };

goto *array[i];

static const int array[] = { &&foo - &&foo,&&bar - &&foo, &&hack - &&foo };

goto *(&&foo + array[i]);

 

嵌套函数

       bar(int *array, int offset, int size)

       {

       __label__failure;

       intaccess (int *array, int index)

        {

          if (index > size)

               goto failure;

          return array[index + offset];

        }

       inti;

       /*... */

       for(i = 0; i < size; i++)

        /* ... */ access (array, i) /* ... */

       /*... */

       return0;

 

       /*Control comes here from access

        if it detects an error.  */

       failure:

       return-1;

       }

 

构造函数调用:使用内建函数记录接收的函数并以相同的参数调用其他函数而无需知道参数类型和个数,还可以记录函数返回值,而无需知道数据类型

       externint myprintf (FILE *f, const char *format, ...);

       externinline __attribute__ ((__gnu_inline__)) int

       myprintf(FILE *f, const char *format, ...)

       {

       intr = fprintf (f, "myprintf: ");

       if(r < 0)

         return r;

       ints = fprintf (f, format, __builtin_va_arg_pack ());

       if(s < 0)

         return s;

       returnr + s;

       }

 

       #ifdef__OPTIMIZE__

       externinline __attribute__((__gnu_inline__)) int

       myopen(const char *path, int oflag, ...)

       {

       if(__builtin_va_arg_pack_len () > 1)

         warn_open_too_many_arguments ();

 

       if(__builtin_constant_p (oflag))

         {

              if((oflag & O_CREAT) != 0 && __builtin_va_arg_pack_len () < 1)

                {

                     warn_open_missing_mode();

                     return__open_2 (path, oflag);

                }

              returnopen (path, oflag, __builtin_va_arg_pack ());

         }

 

       if(__builtin_va_arg_pack_len () < 1)

         return __open_2 (path, oflag);

 

       returnopen (path, oflag, __builtin_va_arg_pack ());

       }

       #endif

 

类型推导

       typeof(typeof (char *)[4]) y;

       #definepointer(T)  typeof(T *)

       #definearray(T, N) typeof(T [N])

       array(pointer (char), 4) y;

#define max(a,b) \

({ __auto_type _a = (a); \

   __auto_type _b = (b); \

 _a > _b ? _a : _b; })

 

不定长数组

struct line {

      int length;

      char contents[0];

};

 

struct line *thisline = (struct line *)

malloc (sizeof (struct line) + this_length);

thisline->length = this_length;

 

FILE *concat_fopen (char *s1, char *s2, char *mode)

{

      char str[strlen (s1) +strlen (s2) + 1];

      strcpy (str, s1);

      strcat (str, s2);

      return fopen (str, mode);

}

 

变长参数宏

#definedebug(format, ...) fprintf (stderr, format, __VA_ARGS__)

       #definedebug(format, args...) fprintf (stderr, format, args)

       #definedebug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)

 

复合常量

struct foo {int a; char b[2];} structure;

structure = ((struct foo) {x + y, 'a', 0});

static struct foo x = (struct foo) {1, 'a', 'b'};

static int y[] = (int []) {1, 2, 3};

static int z[] = (int [3]) {1};

 

指定值初始化

int a[6] = { [4] = 29, [2] = 15 };

int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

int a[6] = { [1] = v1, v2, [4] = v4 };

union foo { int i; double d; };  

union foo f = { .d = 4 };

int whitespace[256] = { [' '] = 1, ['\t'] = 1, ['\h'] = 1, ['\f'] =1, ['\n'] = 1, ['\r'] = 1 };

struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0};

 

范围case

case low ... high:

case 'A' ... 'Z':

case 1 ... 5:

 

强制转换为union

union foo { int i; double d; };

int x;

double y;

union foo u;

u = (union foo) x  ==  u.i = x

u = (union foo) y  ==  u.d = y

 

函数属性

       通用=>aligned    always_inline    const   constructor    destructor    error   warning   

              format    visibility(“default”|”hidden”|”internal”|”protected”)    section

extern int my_printf (void *my_object, const char *my_format, ...)

     __attribute__ ((format(printf, 2, 3)));

       ARM=>long_call    short_call     naked    target(“thumb”|”arm”|”fpu”)

X86=>cdecl    fastcall    thiscall   stdcall   

 

取成员偏移

#defineoffsetof(type, member) __builtin_offsetof (type, member)

 

获取对象大小

#undef memcpy

#define bos0(dest) __builtin_object_size (dest, 0)

#define memcpy(dest, src, n) \

__builtin___memcpy_chk (dest, src, n, bos0 (dest))

 

char *volatile p;

char buf[10];

/* It is unknown what object p points to, so this is optimized

into plain memcpy - no checking is possible.  */

memcpy (p, "abcde", n);

/* Destination is known and length too.  It is known at compile

time there will be no overflow. */

memcpy (&buf[5], "abcde", 5);

/* Destination is known, but the length is not known at compiletime.

This will result in __memcpy_chk call that can check for overflow

at run time.  */

memcpy (&buf[5], "abcde", n);

/* Destination is known and it is known at compile time there will

be overflow.  There will be awarning and __memcpy_chk call that

will abort the program at run time. */

memcpy (&buf[6], "abcde", 5);

 

TLS

__thread int i;

extern __thread struct state s;

static __thread char *p;

 

成员函数指针转普通指针,需指定-Wno-pmf-conversions

extern A a;

extern int(A::*fp)();

typedef int(*fptr)(A *);

fptr p =(fptr)(a.*fp);

fptr p1 = (fptr)(&A::foo);

 

跨平台函数

__attribute__ ((target("default")))

int foo ()

{

  //The default version of foo.

 return 0;

}

 

__attribute__ ((target("sse4.2")))

int foo ()

{

  //foo version for SSE4.2

 return 1;

}

 

__attribute__ ((target("arch=atom")))

int foo ()

{

  //foo version for the Intel ATOM processor

 return 2;

}

 

__attribute__ ((target("arch=amdfam10")))

int foo ()

{

  //foo version for the AMD Family 0x10 processors.

 return 3;

}

 

int main ()

{

 int (*p)() = &foo;

 assert ((*p) () == foo ());

 return 0;

}

 

内联汇编

uint64_t msr;

asm volatile ( "rdtsc\n\t"    // Returns the time in EDX:EAX.

       "shl $32, %%rdx\n\t"  // Shift the upper bits left.

       "or %%rdx, %0"        // 'Or' in the lower bits.

       : "=a" (msr)

       :

       : "rdx");

printf("msr: %llx\n", msr);

// Do other work...

// Reprint the timestamp

asm volatile ( "rdtsc\n\t"    // Returns the time in EDX:EAX.

       "shl $32, %%rdx\n\t"  // Shift the upper bits left.

       "or %%rdx, %0"        // 'Or' in the lower bits.

       : "=a" (msr)

       :

       : "rdx");

printf("msr: %llx\n", msr);

 

int main()

{

      intiInt = 1;

top:

      asmvolatile goto ("some assembler instructions here"

      :/* No outputs. */

      :"q" (iInt), "X" (sizeof(unsigned char) + 1)

      :/* No clobbers. */

      :top);

}

 

指定别名:

       变量别名int foo asm ("myfoo") = 2;

       函数别名int func (int x, int y) asm("MYFUNC");

指定寄存器变量:

       全局寄存器变量

register int *foo asm ("r12");

       局部寄存器变量

int t1 = ...;

register int *p1 asm ("r0") =...;

register int *p2 asm ("r1") =t1;

register int *result asm ("r0");

asm ("sysint" : "=r"(result) : "0" (p1), "r" (p2));

0 0
原创粉丝点击