做人呢,最紧要就系开心啦

GNU中对GCC的语法扩展

1,237次阅读
没有评论

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;
防止两个整数相加,结果溢出;

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