前言:计算机语言是编译器和程序员交流的依据和规范,GNU C是GCC特有的功能,在Linux内核中被广泛应用。
帮助文档:http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/C-Extensions.html#C-Extensions
在GNU C中,可以在结构体中声明某个联合体(或结构体)而不用指出它的名字,如此之后就可以像使用结构体成员一样直接使用其中联合体(或结构体)的成员。
举例,如test.c:
- #include <stdio.h>
- struct test_struct {
- char *name;
- union {
- char gender;
- int id;
- };
- int num;
- };
- int main(void)
- {
- struct test_struct test_struct = {"tanglinux", 'F', 28 };
- printf("test_struct.gender = %c, test_struct.id = %d\n",
- test_struct.gender, test_struct.id);
- return 0;
- }
例子输出结果:
- test_struct.gender = F, test_struct.id = 70
例子中的第17行,结构体变量test_struct直接使用联合体中的成员gender或id。
GCC默认情况下可以使用GNU C的各种扩展功能,如果上例使用C99标准编译的话,会产生以下的错误:
- $ gcc -std=c99 test.c -o test
- test.c:8:6: warning: declaration does not declare anything
- test.c: In function 'main':
- test.c:14:12: warning: excess elements in struct initializer
- test.c:14:12: warning: (near initialization for 'test_struct')
- test.c:17:17: error: 'struct test_struct' has no member named 'gender'
- test.c:17:37: error: 'struct test_struct' has no member named 'id'
修改上例,使其符合C99标准,如test01.c:
- #include <stdio.h>
- union test_union {
- char gender;
- int id;
- };
- struct test_struct {
- char *name;
- union test_union test_union;
- int num;
- };
- int main(void)
- {
- struct test_struct test_struct = {"tanglinux", 'F', 28 };
- printf("test_struct.test_union.gender = %c, test_struct.test_union.id = %d\n",
- test_struct.test_union.gender, test_struct.test_union.id);
- return 0;
- }
例子输出结果:
- $ gcc -std=c99 test01.c -o test01
- test_struct.test_union.gender = F, test_struct.test_union.id = 70
在Linux内核中常用匿名联合(或结构体),如在linux-2.6.38.8/fs/sysfs/sysfs.h文件中struct sysfs_dirent结构体的定义:
- struct sysfs_dirent {
- atomic_t s_count;
- atomic_t s_active;
- #ifdef CONFIG_DEBUG_LOCK_ALLOC
- struct lockdep_map dep_map;
- #endif
- struct sysfs_dirent *s_parent;
- struct sysfs_dirent *s_sibling;
- const char *s_name;
- const void *s_ns; /* namespace tag */
- union {
- struct sysfs_elem_dir s_dir;
- struct sysfs_elem_symlink s_symlink;
- struct sysfs_elem_attr s_attr;
- struct sysfs_elem_bin_attr s_bin_attr;
- };
- unsigned int s_flags;
- unsigned short s_mode;
- ino_t s_ino;
- struct sysfs_inode_attrs *s_iattr;
- };