《深入理解C++11》笔记(第八章. 融入实际的应用)

今天二刷《深入理解C++11》,就顺带把我在印象笔记的摘录传到CSND上,禁止转载!!!

全部笔记链接:

融入实际的应用

1 对齐支持

1.1 数据对齐
#include <iostream>
using namespace std;
struct HowManyBytes{
    char     a;
    int      b;
};
int main() {
    cout << "sizeof(char): " << sizeof(char) << endl;
    cout << "sizeof(int): " << sizeof(int) << endl;
    cout << "sizeof(HowManyBytes): " << sizeof(HowManyBytes) << endl;
    cout << endl;
    cout << "offset of char a: " << offsetof(HowManyBytes, a) << endl;
    cout << "offset of int b: " << offsetof(HowManyBytes, b) << endl;
    return 0;
}
// 编译选项:g++ -std=c++11 8-1-1.cpp
1.2 C++11的alignof和alignas
  • 新标准中为了支持对齐,主要引入两个关键字:操作符alignof、对齐描述符(alignment-specifier)alignas。

alignof(std::max_align_t)

alignas(double) void f(); // 错误:alignas不能修饰函数
alignas(double) unsigned char c[sizeof(double)]; // 正确
extern unsigned char c[sizeof(double)];
alignas(float)
    extern unsigned char c[sizeof(double)]; // 错误:不同对齐方式的变量定义
  • 在C++11标准之前,我们也可以使用一些编译器的扩展来描述对齐方式,比如GNU格式的__attribute__((aligned(8)))就是一个广泛被接受的版本。

  • C++11对于对齐的支持并不限于alignof操作符及alignas描述符。在STL库中,还内建了std::align函数来动态地根据指定的对齐方式调整数据块的位置。该函数的原型如下:

      void* align( std::size_t alignment, std::size_t size, void*& ptr, std::size_t& space );
    

    该函数在ptr指向的大小为space的内存中进行对齐方式的调整,将ptr开始的size大小的数据调整为按alignment对齐。

  • C++11还在标准库中提供了aligned_storage及aligned_union供程序员使用。两者的原型如下:

      template< std::size_t Len, std::size_t Align = /*default-alignment*/ >
      struct aligned_storage;
      template< std::size_t Len, class... Types >
      struct aligned_union;
    

    aligned_storage的第一个参数规定了aligned_storage的大小,第二个参数则是其对齐值。

2 通用属性

2.1 语言扩展到通用属性
  • 不同编译器有不同的属性语法。比如对于g++,属性是通过GNU的关键字__attribute__来声明的。程序员只需要简单地声明:

        __attribute__ ((attribute-list))
    

    即可为程序中的函数、变量和类型设定一些额外信息,以便编译器可以进行错误检查和性能优化等。

extern int area(int n) __attribute__((const));
int main() {
    int i;
    int areas = 0;
    for (i = 0; i < 10; i++) {
      areas += area(3) * i;
    }
}
// 编译选项:g++ -c 8-2-1.cpp

这里的const属性告诉编译器:本函数返回值只依赖于输入,不会改变任何函数外的数据,因此没有任何副作用。在了解该信息的情况下,编译器可以对area函数进行优化处理。area(3)的值只需要计算一次,编译之后可以将area(3)视为循环中的常量而只使用其计算结果,从而大大提高了程序的执行性能。

  • 事实上,在GNU对C/C++的扩展中我们可以看到很多不同的__attribute__属性。常见的如format、noreturn、const和aligned等,具体含义和用法读者可以参考GNU的在线文档http://gcc.gnu.org/onlinedocs/。

  • __declspec
    是微软用于指定存储类型的扩展属性关键字

_declspec(align(32)) struct Struct32 {
    int i;
    double d;
};
2.2 C++11的通用属性
  • C++11语言中的通用属性使用了左右双中括号的形式:

      [[ attribute-list ]]
    

    这样设计的好处是:既不会消除语言添加或者重载关键字的能力,又不会占用用户空间的关键字的名字空间。

  • 事实上,在现有C++11标准中,只预定义了两个通用属性,分别是 [[ noreturn ]]和[[carries_dependency ]] 。而在C++11标准委员会的最初提案中,还包含了形如[[ final ]]、[[ override ]]、[[ restrict ]]、[[ hides ]]、[[ base_check ]]等通用属性。不过最终,标准委员会只通过了以上两个,原因大概有以下几点:

2.3 预定义的通用属性
  • 如上文所述,C++11预定义的通用属性包括[[ noreturn ]]和[[ carries_dependency ]]两种。

  • [[ noreturn ]]是用于标识不会返回的函数的。 这里必须注意,不会返回和没有返回值的(void)函数的区别。没有返回值的void函数在调用完成后,调用者会接着执行函数后的代码;而 不会返回的函数在被调用完成后,后续代码不会再被执行。 [[noreturn]]主要用于标识那些不会将控制流返回给原调用函数的函数,典型的例子有:有终止应用程序语句的函数、有无限循环语句的函数、有异常抛出的函数等。

      [[noreturn]] void abort(void) noexcept;
    
  • [[ carries_dependency ]]则跟并行情况下的编译器优化有关。事实上,[[carries_dependency]]主要是为了解决弱内存模型平台上使用memory_order_consume内存顺序枚举问题。
    具体略。

3 Unicode支持

3.1 字符集、编码和Unicode
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值