联合体(union)在结构体(struct)中的初始化(gcc语法)

今天编译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如下。

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中),不能在结构体初始化时,直接地同结构体的普通成员一样初始化。当然如果定义结构体时顺便定义其中的联合体,那么是可以在结构体初始化时,就一起初始化联合体里面的成员。说的很绕,可能没表达的很清楚,还是看下面的代码吧。

/* 
 * 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 

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;
}

master

Stay hungry, stay foolish.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

*