GNU中对GCC的语法扩展

1,262次阅读
没有评论

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