GNU中对GCC的语法扩展

1,224次阅读
没有评论

1.在GNU C语言中,括号里的复合语句可以看作一个表达式;

#define max(a,b) ((a) > (b)?(a):(b))
#define max(a,b) \
({int _a = (a), _b = (b);(_a) > (_b)?(_a):(_b)})

2.零长数组

struct line {
int length;
char data[0];
};
struct line *shisline=malloc(sizeof(struct line) + this_length);
thisline->length = this_length;
sizeof(struct line) = sizeof(int);

3.case范围

case可以用一个范围做标签

case 'a'...'z':

4.标号元素

标准C语言要求数组或结构体,必须按固定顺序出现;但GNU C可以通过制定索引或结构体成员名来初始化,不必按固定顺序;

static const struct file_operations zero_fops = {
.llseek = zero_lseek,
.write = write_zero,
.read_iter = read_iter_zero,
.read = read_zero,
.write_iter = write_iter_zero,
.mmap = mmap_zero,
.get_unmapped_area = get_unmapped_area_zero,
#ifndef CONFIG_MMU
.mmap_capabilities = zero_mmap_capabilities,
#endif
};

未初始化成员为0,或者NULL。

5.可变参数

#define printk(fmt, ...) printf(fmt, ##__VA_ARGS__)

"..."代表一个可以变化的参数表,"__VA_ARGS__"是编译器保留字段,预处理时把参数传递给宏。

6.函数属性

GNU C允许声明函数属性,变量属性和类型属性,以便编译器进行特定优化和代码检查。
attribute((attribute-list))
常用的有noreturn , format const,interrupt,isr等;

#ifndef __pure
#define __pure __attribute__((pure))
#endif
#define noinline __attribute__((noinline))
#ifndef __packed
#define __packed __attribute__((packed))
#endif
#ifndef __noreturn
#define __noreturn __attribute__((noreturn))
#endif
#ifndef __aligned
#define __aligned(x) __attribute__((aligned(x)))
#endif
#define __printf(a, b) __attribute__((format(printf, a, b)))
#define __scanf(a, b) __attribute__((format(scanf, a, b)))

__aligned(x):规定变量或结构体成员的最小对齐格式,单位字节;
packed属性使变量或结构体成员使用最小的对齐方式;

struct test
{
char a;
int x[2] __attribute__((packed));
}
sizeof(struct test) = 9bytes;

7.内建函数

"_builtin" 作为前缀
__builtin_constant_p(x):判断x是否在编译时就可以确定为常量,是则返回1,否则返回0;

__builtin_expect(exp,c):exp==c的概率很大,用来引导GCC编译器进行条件分支预测,优化指令序列,提高CPU预取指令的正确性;

# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)

__builtin_prefetch(const void*addr, int rw, int locality):主动进行预取,在使用addr之前,
就把其值加载到cache中,减少读取的延迟,提高性能;
addr:要预取数据的地址;
rw:表示读写属性,1为可写,0表示只读;
locality:表示数据在cache中的时间局部性,其中0表示读取完addr之后不用保留在cache中,而1~3表示时间局部性逐渐增强;

void __free_pages_core(struct page *page, unsigned int order)
{
unsigned int nr_pages = 1 << order;
struct page *p = page;
unsigned int loop;
/*
* When initializing the memmap, __init_single_page() sets the refcount
* of all pages to 1 ("allocated"/"not free"). We have to set the
* refcount of all involved pages to 0.
*/
prefetchw(p);
for (loop = 0; loop < (nr_pages - 1); loop++, p++) {
prefetchw(p + 1);
__ClearPageReserved(p);
set_page_count(p, 0);
}
__ClearPageReserved(p);
set_page_count(p, 0);
atomic_long_add(nr_pages, &page_zone(page)->managed_pages);
/*
* Bypass PCP and place fresh pages right to the tail, primarily
* relevant for memory onlining.
*/
__free_pages_ok(page, order, FPI_TO_TAIL | FPI_SKIP_KASAN_POISON);
}

8.UL

1:表示有符号整型数字1;
1UL:表示无符号长整型数字1;
防止两个整数相加,结果溢出;

正文完
 0
admin
版权声明:本站原创文章,由 admin 于2022-03-10发表,共计2546字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
粤ICP备2021172357号-1