me
me copied to clipboard
学习 C/C++ (Part 18: struct)
今天在obs看到这样一句代码
struct encoder_packet packet = {.type = OBS_ENCODER_VIDEO, .timebase_den = 1, .keyframe = true};
查了一下这个叫做Designated Initializers,不限于struct,gcc的文档中描述: Standard C90中初始化必须按顺序执行,在ISO C99中扩展支持指定初始化。
Array
int a[6] = { [4] = 29, [2] = 15 };
等同于 int a[6] = { 0, 0, 15, 0, 29, 0};
Struct
struct point { int x, y}
对应初始化
struct point p { .y = 1, .x = 3 };
等同于
struct point p { 3, 1 };
注: Designated Inits仅支持C,不支持C++,竟然还有这么好的事情。。。
历史回顾
- 1967年,Martin Richards为写操作系统和编译器开发了BCPL 随后,Ken Thompson改进BCPL,形成了B,取B是因为ALGOL 60中的字母A
- 1970年,Ken在贝尔实验室(如果你对贝尔实验室没有概念的话,可以看一下浪潮之巅,就知道当时有多牛X)用B在DEC PDP-7写了第一个UNIX
- 1973年,Dennis Ritchie为了将UNIX从PDP-7移植到PDP-11上,在B的基础上形成C,并用C重写了UNIX,至此形成C的原型
- 1978年,Dennis Ritchie和Brian Kernighan合写了K&R C
- 1989年,为了解决不兼容问题,ANSI对C进行了标准化,此标准称为C89
- 1999年,针对C89进行了一些更新,此版本称为C99
- 2011年12月8日,ISO正式发布了新的C语言的新标准C11,之前被称为C1X,官方名称为ISO/IEC 9899:2011
从1973年算起,也差不多有40年了,其中主要的4个版本
- Classic C (K&R C)
- C89 (C90) ANSI C (ANSI: 美国国家标准化协会)
- C99: 引入许多特性,包括内联函数、可变数组、指定成员的初始化器等等,但编译器到目前为止并未100%实现,gcc, clang支持达90%以上,微软的C编译器最能支持到70%左右
- C11: 引入字节对齐,范型机制(generic selection),多线程,静态断言,unicode。
参考: C89(C90)、C99、C11——C语言的三套标准
印象中,在C语言中局部变量的定义必须是在函数开头的,其实这是C89的规范,到了C99取消了这个限制,变量可以在任意位置定义。包括ANSI C不允许在for定义i,必须先int i
再for,看来选对标准非常重要。
c.c
#include <stdio.h>
int main(void) {
#ifdef __STDC_VERSION__
printf("__STDC_VERSION__ = %ld \n", __STDC_VERSION__);
#endif
#ifdef __STRICT_ANSI__
puts("__STRICT_ANSI__");
#endif
return 0;
}
Test with (c.sh):
#!/usr/bin/env bash
for std in c89 c99 c11 c17 gnu89 gnu99 gnu11 gnu17; do
echo $std
gcc -std=$std -o c.out c.c
./c.out
echo
done
echo default
gcc -o c.out c.c
./c.out
Outcome:
% ./c.sh
c89
__STRICT_ANSI__
c99
__STDC_VERSION__ = 199901
__STRICT_ANSI__
c11
__STDC_VERSION__ = 201112
__STRICT_ANSI__
c17
__STDC_VERSION__ = 201710
__STRICT_ANSI__
gnu89
gnu99
__STDC_VERSION__ = 199901
gnu11
__STDC_VERSION__ = 201112
gnu17
__STDC_VERSION__ = 201710
default
__STDC_VERSION__ = 201710
可以看到gcc还是clang目前采用的已经是gun17。C17并未引入新的语言特性,只对C11进行了补充和修正。此外,C17和gun17应该是一回事,两个写法。