前言 - 需要点开头

  C11标准是C语言标准的第三版(2011年由ISO/IEC发布),前一个标准版本是C99标准。

相比C99,C11有哪些变化呢!!所有的测试全部基于能够和标准贴合的特性平台. 但是绝大部

分来源于 GCC. 这里不妨教大家源码安装最新的GCC吧。

a. 首先去 GNU GCC官网下载最新的 GCC 源码

  GCC  : https://gcc.gnu.org/

下载最新源码, 安装过程中可能提示下面这句话

configure: error: Building GCC requires GMP 4.2+, MPFR 2.4.+ and MPC 0.8.+.

说白了缺少上面 GMP,MPFR,MPC 三个组件。 那么开始下载

  GMP  : ftp://ftp.gnu.org/gnu/gmp/

  MPFR: http://www.mpfr.org/mpfr-current/

  MPC  : ftp://ftp.gnu.org/gnu/mpc/

b. 开始挨个解压安装 GMP → MPFR → MPC → GCC

开始执行命令跑起来。

cd gmp-6.1./
mkdir gmp-6.1.-build
cd gmp-6.1.-build
../configure

我们如果出现

checking for suitable m4... configure: error: No usable m4 in $PATH or /usr/5bin (see config.log for reasons).

不用怕,那就继续安装 m4

  m4ftp://ftp.gnu.org/gnu/m4/

cd m4-1.4.

mkdir m4-1.4.-build

cd m4-1.4.-build

../configure

make

sudo make install

那继续安装 GMP。

cd ../../gmp-6.1. /gmp-6.1.-build

../configure

make

sudo make install

随后就是 MPFR

cd ../../mpfr-3.1.

mkdir mpfr-3.1.-build

cd mpfr-3.1.-build

../configure

make

sudo make install

然后就是 MPC

cd ../../mpc-1.0.

mkdir mpc-1.0.-build

cd mpc-1.0.-build

../configure

make

sudo make install

最后还是回到我们的 gcc

cd ../../gcc-7.2.

mkdir gcc-7.2.-build

cd gcc-7.2.-build

../configure

又是不好意思,提示下面错误信息

configure: error: I suspect your system does not have -bit development libraries (libc and headers). 
If you have them, rerun configure with --enable-multilib. If you do not have them,
and want to build a -bit-only compiler, rerun configure with –disable-multilib.

继续

../configure --enable-multilib

make

不好意思又来了

checking dynamic linker characteristics... configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES.
Makefile:: recipe for target 'configure-stage1-zlib' failed
make[]: *** [configure-stage1-zlib] Error
make[]: Leaving directory '/home/wangzhi/桌面/gcc-7.2.0/gcc-7.2.0-build'
Makefile:: recipe for target 'stage1-bubble' failed
make[]: *** [stage1-bubble] Error
make[]: Leaving directory '/home/wangzhi/桌面/gcc-7.2.0/gcc-7.2.0-build'
Makefile:: recipe for target 'all' failed
make: *** [all] Error

没关系我们继续搞,存在首次安装GCC不彻底污染问题,清理后继续安装

make distclean

../configure –enable-multilib

make

还是不行更换思路, 走插件全安装

sudo apt-get install gawk

sudo apt-get install gcc-multilib
sudo apt-get install binutils
sudo apt-get install lzip make distclean ../configure make sudo make install

见过漫长的等待,下面就是见证历史奇迹的时候了。

到这里关于 GCC 升级到最新版本问题以及搞定。

正文  -  C11标准特性研究

1对齐处理

  alignof(T)返回T的对齐方式,aligned_alloc()以指定字节和对齐方式分配内存,头文件<stdalign.h>

定义了这些内容。我们首先看看 stdalign.h 中定义

/* ISO C1X: 7.15 Alignment <stdalign.h>.  */

#ifndef _STDALIGN_H
#define _STDALIGN_H #ifndef __cplusplus #define alignas _Alignas
#define alignof _Alignof #define __alignas_is_defined 1
#define __alignof_is_defined 1 #endif #endif /* stdalign.h */

alignas 设置内存的对其方式, alignof 返回内存的对其方式。

Aligned.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdalign.h> #define _INT_NAME (128) struct names {
int len;
char name[];
}; struct people {
int id;
alignas(struct names) char name[sizeof(struct names) + _INT_NAME];
}; static void test_aligned(void) {
printf("sizeof(struct people) = %zu.\n", sizeof(struct people)); // 控制内存布局
struct people pe = { };
struct names * name = (struct names *)pe.name;
name->len = _INT_NAME;
strcpy(name->name, "你好吗?");
printf("people len = %d, name = %s.\n", pe.id, name->name); // 测试内存对其
printf("alignof(struct people) = %zu.\n", alignof(struct people)); // 接着控制内存布局
alignas(struct names) char xname[sizeof(struct names) + _INT_NAME];
struct names * xna = (struct names *)xname;
strcpy(xna->name, "我还行!"); //
// 另一种内存申请, 一种演示, malloc已经够额
// aligned_alloc 相比 malloc 多了第一个参数, 这个参数必须是2的幂
// 在特定嵌入式平台会使用
//
void * ptr = aligned_alloc(alignof(struct names), _INT_NAME);
if (NULL == ptr)
exit(EXIT_FAILURE);
free(ptr);
}

2 _Noreturn

  _Noreturn是个函数修饰符,位置在函数返回类型的前面,声明函数无返回值,

有点类似于gcc的__attribute__((noreturn)),后者在声明语句尾部。

#include <stdio.h>
#include <stdlib.h> _Noreturn static void _test(void) {
puts("func _test C11 never returns");
abort();
} int main(int argc, char * argv[]) {
_test();
}

3 _Generic

  _Generic支持轻量级范型编程,可以把一组具有不同类型而却有相同功能的函数抽象为一个接口。

#include <stdio.h>

void sort_insert_int(int a[], int len);
void sort_insert_float(float a[], int len);
void sort_insert_double(double a[], int len); #define sort_insert(a, len) \
_Generic(a, \
int * : sort_insert_int, \
float * : sort_insert_float, \
double * : sort_insert_double)(a, len) //
// file : generic.c
// test : C11 泛型用法
//
int main(int argc, char * argv[]) {
int a[] = { , , , , , , , , , , , };
int i, len = sizeof a / sizeof (*a); sort_insert(a, len); for (i = ; i < len; ++i)
printf("%2d ", a[i]);
putchar('\n'); return ;
} #define sort_insert_definition(T) \
void \
sort_insert_##T (T a[], int len) { \
int i, j; \
for (i = ; i < len; ++i) { \
T key = a[j = i]; \
while (j > && a[j - ] < key) { \
a[j] = a[j - ]; \
--j; \
} \
a[j] = key; \
} \
} sort_insert_definition(int)
sort_insert_definition(float)
sort_insert_definition(double)

最终输出结果如下

4 _Static_assert()

  _Static_assert(),静态断言,在编译时刻进行,断言表达式必须是在编译时期可以计算的表达式,

而普通的assert()在运行时刻断言。

#include <stdio.h>

int main(void) {
printf("C version : %ld.\n", __STDC_VERSION__); _Static_assert(__STDC_VERSION__ < 201112L, "It is c11 version"); return ;
}

其实本质等同于, 真的有点鸡肋

#if __STDC_VERSION__ >= 201112L
# error "It is c11 version"
#endif

5、安全版本的几个函数

  gets_s()取代了gets(),原因是后者这个I/O函数的实际缓冲区大小不确定,

以至于发生常见的缓冲区溢出攻击,类似的函数还有其它的。

_Success_(return != )
_ACRTIMP char* __cdecl gets_s(
  _Out_writes_z_(_Size) char* _Buffer,
  _In_ rsize_t _Size
  );

目前在 VS 中有这个函数实现. C11 废弃了 gets, 这里是最接近的 api, 相比 fgets 它不会记录最后一个 '\n'.

并且会在最后一个字符添加 '\0'. 其中 rsize_t 和 size_t 类型是一样的, 但是

#if __STDC_WANT_SECURE_LIB__
typedef size_t rsize_t;
#endif #if __STDC_WANT_SECURE_LIB__
#ifndef RSIZE_MAX
#define RSIZE_MAX (SIZE_MAX >> 1)
#endif
#endif

也就是 gets_s 第二参数合法区间就是 [1, RSIZE_MAX], 否则它会什么都不做.

6 fopen() 新模式

  fopen() 增加了新的创建、打开模式“x”,在文件锁中比较常用。类似 POSIX 中的

O_CREAT | O_EXCL. 文件已存在或者无法创建(一般是路径不正确)都会导致 fopen

失败。文件以操作系统支持的独占模式打开。可惜的是当前 CL or GCC 都没有提供支持.

主要原因是 glibc 没有提供支持!

7匿名结构体、联合体。

  例如下面这样, 直接 struct cjson::vs 这种访问. 一种语法层面优化.

struct cjson {
struct cjson * next;
struct cjson * child; unsigned char type;
char * key;
union {
char * vs;
double vd;
};
};

8多线程

  头文件<threads.h>定义了创建和管理线程的函数,新的存储类修饰符_Thread_local限定了变

量不能在多线程之间共享。只能等待 glibc 去支持, 单纯而言可以将 pthread 引入标准线程库.

_Thread_local 等价于线程 pthread_key_t 的私有变量, 不是特别适合不推荐使用.

9 _Atomic类型修饰符和头文件<stdatomic.h>

  原子操作也算是 C11 看着 C++11 急眼了, 直接引入的类型. 把编译器提供的特性纳入标准中.

同样支持的很一般般. 但是可以一用. 展示一种最简单的自旋锁写法:

include <stdatomic.h>

// 标记类型, init lock
atomic_flag flag = ATOMIC_FLAG_INIT; // 尝试设置占用(原子操作), try lock
atomic_flag_test_and_set(&flag); // 释放(原子操作), unlock
atomic_flag_clear(&flag);

10、改进的Unicode支持和头文件<uchar.h>

  提供了utf-8和 utf-16, utf-32 字符之间转换. 其中 uchar.h 在 winds 一种实现如下:

//
// uchar.h
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// #pragma once
#define _UCHAR #include <corecrt.h> _CRT_BEGIN_C_HEADER #define __STDC_UTF_16__
#define __STDC_UTF_32__ typedef unsigned short _Char16_t;
typedef unsigned int _Char32_t; #if !defined __cplusplus || (defined _MSC_VER && _MSC_VER < 1900)
typedef unsigned short char16_t;
typedef unsigned int char32_t;
#endif _Check_return_ _ACRTIMP size_t __cdecl mbrtoc16(_Out_opt_ char16_t *_Pc16, _In_reads_or_z_opt_(_N) const char *_S, _In_ size_t _N, _Inout_ mbstate_t *_Ps);
_Check_return_ _ACRTIMP size_t __cdecl c16rtomb(_Out_writes_opt_() char *_S, _In_ char16_t _C16, _Inout_ mbstate_t *_Ps); _Check_return_ _ACRTIMP size_t __cdecl mbrtoc32(_Out_opt_ char32_t *_Pc32, _In_reads_or_z_opt_(_N) const char *_S, _In_ size_t _N, _Inout_ mbstate_t *_Ps);
_Check_return_ _ACRTIMP size_t __cdecl c32rtomb(_Out_writes_opt_() char *_S, _In_ char32_t _C32, _Inout_ mbstate_t *_Ps); _CRT_END_C_HEADER /*
* Copyright (c) 1992-2013 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V6.40:0009 */

使用起来也很简单.

#include <stdio.h>
#include <uchar.h>
#include <locale.h>
#include <string.h> //
// uchar test
//
int main(int argc, char * argv[]) {
size_t i, len;
const char * str = u8"z\u00df\u6c34\U0001F34C"; // 或 u8"zß水

C11 标准特性研究的更多相关文章

  1. C89标准和C99标准C11标准的区别

    转载 C89标准和C99标准C11标准的区别 C99对C89的改变 1.增加restrict指针 C99中增加了公适用于指针的restrict类型修饰符,它是初始访问指针所指对象的惟一途径,因此只有借 ...

  2. PHP5.4.0新特性研究

    PHP5.4.0新特性研究 1.内建Web Server 这的确是个好的改进,大大的方便了开发人员.以后开发机不装nginx,httpd也行 cd $PHP_INSTALL_PATH ./bin/ph ...

  3. GCC 版本与C11标准

    1. GCC版本是否支持C11 C89=C90:gcc选项是:-ansi, -std=c90 or -std=iso9899:; 带了GNU扩展的:-std=gnu90 C94=C95:gcc选项:- ...

  4. c11标准

    在编译器vs13及其以上可以使用 编译器对语言的一种优化 1.变量初始化 int a=0,a(10),a{10};定义a的值的三种方式 2.nullptr 相当于c的null 有类型 更加的安全 3. ...

  5. Oracle 12C In-Memory特性研究

    Oracle 12C In-Memory特性研究一.Oracle In-Memory1.1 In-Memory 开启方法1.2 开启与关闭IM column store1.3 inmemory优先级调 ...

  6. [转]Java se 7 最新特性研究(一)

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp81   从2006到现在等待了多年的jdk7终于发布了.这里将对它的一些 ...

  7. Maclean Liu对Oracle Database 12c新特性研究汇总

    Maclean Liu关于DB 12c新特性的研究文章如下: [Oracle Database 12c新特性] In-Database Archiving数据库内归档 [Oracle Database ...

  8. [转] Java se 7新特性研究(二)

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp82   今天主要研究Java se 7中异常处理的新功能.从今天开始正在 ...

  9. 是我out了,c11标准出炉鸟

    gcc -std=c11 -Wall -O3 -g0 -s -o x.c x 或者 clang -std=c11 -Wall -O3 -g0 -s -o x.c x 来吧! 我是有多无聊啊 测试代码: ...

随机推荐

  1. 【bzoj2591】[Usaco 2012 Feb]Nearby Cows 树形dp

    题目描述 Farmer John has noticed that his cows often move between nearby fields. Taking this into accoun ...

  2. BZOJ 3040最短路

    题目描述 给定一个 NN 个点, MM 条有向边的带权图,请你计算从 SS 出发,到每个点的距离. 数据保证你能从 SS 出发到任意点. 输入输出格式 输入格式: 第一行两个整数 NN . MM ,表 ...

  3. AOP拦截+权限验证+返回默认接口对象

    接口如:public IList<string> TestAOP(string token); public IMethodReturn Invoke(IMethodInvocation ...

  4. 【Codeforces Round #404 (Div. 2)】题解

    A. Anton and Polyhedrons 直接统计+答案就可以了. #include<cstdio> #include<cstring> #include<alg ...

  5. [SDOI2014][BZOJ3533] 向量集 [线段树+凸包]

    题面 BZOJ传送门 思路 首先当然是推式子 对于一个询问点$(x_0,y_0$和给定向量$(x_1,y_1)$来说,点积这么表达: $A=x_0x_1+y_0y_1$ 首先肯定是考虑大小关系:$x_ ...

  6. 函数strcat实现

    1.函数原型 extern char *strcat(char *dest,const char *src); 注:在C++中,则存在于<cstring>头文件中. 2.函数功能: str ...

  7. ImageNet: what is top-1 and top-5 error rate?

    https://stats.stackexchange.com/questions/156471/imagenet-what-is-top-1-and-top-5-error-rate Your cl ...

  8. Codeforces Round #547 (Div. 3) 题解

    Codeforces Round #547 (Div. 3) 题目链接:https://codeforces.com/contest/1141 A,B咕咕了... C. Polycarp Restor ...

  9. How far away ? LCA求树上两点距离

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  10. bzoj 1098 [POI2007]办公楼biu bfs+补图+双向链表

    [POI2007]办公楼biu Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1543  Solved: 743[Submit][Status][Di ...