在GUN C
中,支持通过标号元素来对指定结构体成员名进行初始化,这允许初始化值以任意顺序出现。
在Linux
内核中对init_mm
初始化时有如下代码。
#define INIT_MM_CONTEXT(name) \
.pgd = init_pg_dir,
struct mm_struct init_mm = {
.mm_rb = RB_ROOT,
.pgd = swapper_pg_dir,
.mm_users = ATOMIC_INIT(2),
.mm_count = ATOMIC_INIT(1),
.write_protect_seq = SEQCNT_ZERO(init_mm.write_protect_seq),
MMAP_LOCK_INITIALIZER(init_mm)
.page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
.arg_lock = __SPIN_LOCK_UNLOCKED(init_mm.arg_lock),
.mmlist = LIST_HEAD_INIT(init_mm.mmlist),
.user_ns = &init_user_ns,
.cpu_bitmap = CPU_BITS_NONE,
INIT_MM_CONTEXT(init_mm)
};
其中对.pgd
进行了两次赋值,第一次是.pgd = swapper_pg_dir,
,而最后,又使用INIT_MM_CONTEXT
宏对其进行了赋值,那结果如何呢?
请看如下测试代码:
#include <stdio.h>
#define __pr(x) printf("%-40s: %d\n", #x, x)
struct test {
int a;
int b;
int c;
};
int main(void)
{
struct test val = {
.a = 1,
.c = 2,
.a = 3, // final val
};
__pr(val.a);
__pr(val.b);
__pr(val.c);
return 0;
}
测试结果
val.a : 3
val.b : 0
val.c : 2
从测试结果来看,最终结果以最后一次赋值为准。
除了结构体可以覆盖之前的值外,数组的赋值也有类似特性,如kernel/time/hrtimer.c
中
static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = {
/* Make sure we catch unsupported clockids */
[0 ... MAX_CLOCKS - 1] = HRTIMER_MAX_CLOCK_BASES,
[CLOCK_REALTIME] = HRTIMER_BASE_REALTIME,
[CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC,
[CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME,
[CLOCK_TAI] = HRTIMER_BASE_TAI,
};