今天编译kvm upstream时,发现如下的错误,是一个struct里面的union的初始化时的语法错误,所以简单总结了一下。本博客中提及的对C的编译,默认情况下,使用的是GCC作为编译器(gcc version >= 4.4.0)。
arch/x86/kvm/pmu.c: In function 'reprogram_counter':
arch/x86/kvm/pmu.c:173: error: unknown field 'sample_period' specified in initializer
我写了一个patch去fix这个问题,发到kvm mailing list中,redhat的人告诉说已经在kvm next tree中fix过了;不过我只改了两行的patch如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index 061a03f..8f142bf 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -170,9 +170,9 @@ static void reprogram_counter(struct kvm_pmc *pmc, u32 type, .exclude_host = 1, .exclude_user = exclude_user, .exclude_kernel = exclude_kernel, - .sample_period = (-pmc->counter) & pmc_bitmask(pmc), .config = config, }; + attr.sample_period = (-pmc->counter) & pmc_bitmask(pmc), event = perf_event_create_kernel_counter(&attr, -1, current, intr ? kvm_perf_overflow_intr : |
这个问题就在于union中的成员(这个union在一个struct中),不能在结构体初始化时,直接地同结构体的普通成员一样初始化。当然如果定义结构体时顺便定义其中的联合体,那么是可以在结构体初始化时,就一起初始化联合体里面的成员。说的很绕,可能没表达的很清楚,还是看下面的代码吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
/* * This sample shows definition and initiation of a struct and a union in a struct. * using GCC to compile this C file * Author: Jay Ren */ #include <stdio.h> int main(int argc, char *argv[]) { struct my_struct1 { int num1; union { int num2; char ch; }; }; struct my_struct1 my_st1 = { .num1 = 111, /* the following commented line will cause a syntax error. */ /* .num2 = 123456,*/ }; /* num2 or ch in the union of the struct can't be initiated before. */ my_st1.num2 = 123456; printf("my_st1.num1 = %d\n", my_st1.num1); printf("my_st1.num2 = %d\n", my_st1.num2); struct my_struct2 { int num1; union my_union { int num2; char ch; } my_u; }; struct my_struct2 my_st2 = { .num1 = 222, /* the following line for initiating num2 works fine. */ .my_u.num2 = 123456, }; printf("my_st2.num1 = %d\n", my_st2.num1); printf("my_st2.num2 = %d\n", my_st2.my_u.num2); return 0; } |