gcc语法

gcc语法扩展实例分析 /* * Copyright (C) 1998-2006 [email protected] * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. */ #include #include #include /* 1. 语句表达式 和Typeof GNU C 把包含在括号中的复合语句看做是一个表达式,称为语句表达式,它可以出 现在任何允许表达式的地方,你可以在语句表达式中使用循环、局部变量等,原本 只能在复合语句中使用。.复合语句的最后一个语句应该是一个表达式,它的值将成 为这个语句表达式的值。 #define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) #define min(X, Y) (__extension__ ({typeof (X) __x = (X), __y = (Y); (__x < __y) ? __x : __y; })) 在标准 C 中,通常定义为: #define min(x,y) ((x) < (y) ? (x) : (y)) 利用 typeof 可以定义更通用的宏,不必事先知道参数的类型, typeof(x) 表示 x 的值类型,例如: */ #define min(x,y) ({ const typeof(x) _x = (x); const typeof(y) _y = (y); (void) (&_x == &_y);_x < _y ? _x : _y; }) //2.可变参数宏 可以看博客上的文章 #define pr_debug(fmt,arg...) printf(fmt,##arg) #define err(...) fprintf(stderr, __VA_ARGS__)//可变参数宏 #define err1(...) fprintf(stderr, ##__VA_ARGS__) #define TEST(ARGTERM...) printf("test is "#ARGTERM" /n") #define PASTE(a, b) a##b /* 3.零长度数组 GNU C 允许使用零长度数组,在定义变长对象的头结构时,这个特性非常有用。 结构的最后一个元素定义为零长度数组,它不占结构的空间。在标准 C 中则需要 定义数组长度为 1,分配时计算对象大小比较复杂。 */ struct test { int inode; char name[0]; }; //5.标号元素 struct print_t { void (*print1)(char * is); void (*print2)(char * is); } ; void print_string1(char *is) { printf("%s/n",is); } void print_string2(char *is) { printf("%s/n",is); } /* 4.声明的特殊属性 GNU C 允许声明函数、变量和类型的特殊属性,以便手工的代码优化和更仔细的代 码检查。要指定一个声明的属性,在声明后写 __attribute__ (( ATTRIBUTE ))。 __attribute__可以设置函数属性(Function Attribute)、变量属性 (Variable Attribute)和类型属性(Type Attribute)。 其中 ATTRIBUTE 是属性说明,多个属性以逗号分隔。GNU C 支持十几个属性,这 里介绍最常用的: (1) noreturn 属性 noreturn 用于函数,表示该函数从不返回。这可以让编译器生成稍微优化的 代码,最重要的是可以消除不必要的警告信息比如未初使化的变量 (2)* format (ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK) 属性 format 用于函数,表示该函数使用 printf, scanf 或 strftime 风格的参 数,使用这类函数最容易犯的错误是格式串与参数不匹配,指定 format 属性可以 让编译器根据格式串检查参数类型。 (3)* unused 属性 unused 用于函数和变量,表示该函数或变量可能不使用,这个属性可以避免 编译器产生警告信息。 (4)* section ("section-name") 属性 section 用于函数和变量,通常编译器将函数放在 .text 节,变量放在 .data 或 .bss 节,使用 section 属性,可以让编译器将函数或变量放在指定的节中 (5)aligned (alignment) 该属性规定变量或结构体成员的最小的对齐格式,以字节为单位。例如: int x __attribute__ ((aligned (16))) = 0; 编译器将以16字节(注意是字节byte不是位bit)对齐的方式分配一个变量。 cleanup,common,nocommon,deprecated,mode,section,shared,tls_model, transparent_union,unused,vector_size,weak,dllimport,dlexport 等 更多请看attribute详解 */ // 最小字节对齐 1+8+1+1+4 =15个字节 ;attribute 对char 无效 struct aligned_test { char a ; int x[2] ; char b; char c; int d ; } __attribute__ ((packed)); // 默认排列 4 + 8 + 4(b ,c)+4 = 20个字节 //4字节对其 struct no_aligned_test { char a; int x[2]; char b; char c; int d; }; //8+8+(1+1+4=8) = 24个字节 struct nn_aligned_test { char a ; int x[2]; char b; char c; int d ; } __attribute__ ((aligned (8))) ; __attribute__ (( noreturn)) void go_out(void) { exit(0); } main(int argc, char *argv[]) { const int i1=40; const int * p1; int i2=9; int * pi2; const int * const p3=&i1; p1=&i2; /* char mystr[]={"xyz"}; char *myp=mystr; printf("%s/n",mystr); myp++; //mystr++ //数组名字不能加 printf("%s/n",myp); */ char *str[]={"abcdefg","123456"}; char **pp; pp=str; printf("%s/n",str[0]); *pp++; //*(pp++); //printf("%s/n",*pp++); printf("%s/n",*pp); /* 5.标号元素赋值 将结构my_print的 元素 print1初始化为 print_string1, 元素 print2初始化为 print_string2, 这是 GNU C 扩展中最好的特性之一,当结构的定义变化以至元素的偏移改变时,这种初始化方法仍然 保证已知元素的正确性。对于未出现在初始化中的元素,其初值为 0 */ struct print_t my_print = { print1: print_string1, print2: print_string2, }; int i=10,j=20; char *PASTE(str,1) ="string"; err ("i=%d/n", i); err("hello/n"); err1("i=%d/n", i); err1("hello/n"); TEST(123); printf("%d/n",min(i,j)); printf("%s/n",PASTE(str,1)); printf("sizeof(struct test)=%d/n",sizeof(struct test)); printf("sizeof(struct aligned_test)=%d/n",sizeof(struct aligned_test)); printf("sizeof(struct no_aligned_test)=%d/n",sizeof(struct no_aligned_test)); printf("sizeof(struct n_aligned_test)=%d/n",sizeof(struct nn_aligned_test)); my_print.print1("eeeeeeeeeeeeeeeee") ; /* 6.Case 范围 GNU C 允许在一个 case 标号中指定一个连续范围的值,例如: case '0' ... '9': 相当于 case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': */ switch('5'){ case '0' ... '9': printf("0-9/n");; break; case 'a' ... 'f': printf("a-f/n"); break; case 'A' ... 'F': printf("A-F/n");break; } go_out(); }

你可能感兴趣的:(struct,String,gcc,编译器,deprecated,alignment)