自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(20)
  • 收藏
  • 关注

原创 静态程序分析03

通过活跃变量分析和常量传播进行死代码消除优化。

2023-09-07 13:10:21 84

原创 静态程序分析02

变量在程序中只有三种状态UNDEF、CONSTANT、NAC。

2023-09-06 16:02:52 257 1

原创 静态程序分析01

(Live Variable Analysis)是编译器优化和静态分析的一项重要技术,用于确定在程序的每个程序点(通常是每个基本块的出口)上哪些变量仍然是“活跃”的,也就是在程序执行到该点时仍然会被使用。:在编译器优化中,了解哪些变量在每个程序点上仍然是活跃的,有助于进行寄存器分配。只有活跃的变量需要存储在寄存器中,因此可以在寄存器之间有效地分配变量,以最大程度地减少内存访问。:在静态分析中,了解哪些变量在程序中不再被使用,有助于进行死代码消除。

2023-09-05 15:34:51 280 1

原创 现代C++语言核心特性解析part22

实现一个自己的std::pair} T1 first;T2 second;编译出错了,编译器提示T2是一个char [6]类型。由于std::pair和MyPair构造函数的形参都是引用类型,因此从构造函数的角度它们都无法触发数组类型的衰退。但无论是std::make_pair还是std::pair,都有自己的办法让数组类型衰退为指针。

2023-04-26 16:20:43 290

原创 现代C++语言核心特性解析part20

函数体内定义了一个int类型的数组tmp,并且借用了逗号表达式的特性,在括号中用逗号分隔的表达式会以从左往右的顺序执行,最后返回最右表达式的结果。是一个包展开,而(std::cout

2023-04-25 18:56:48 136

原创 现代C++语言核心特性解析part18

第34章 基础特性的其他优化(C++11~C++20)34.1 显式自定义类型转换运算符(C++11)#include <iostream>#include <vector>template<class T>class SomeStorage {public: SomeStorage() = default; SomeStorage(std::initializer_list<T> l) : data_(l) {}; operator boo

2023-04-25 14:57:36 126

原创 现代C++语言核心特性解析part17

一般情况下,主线程的执行会比IO线程快,所以主线程调用await_ready的时候ready_更可能为false,这时代码会执行await_suspend函数,await_suspend函数创建新线程等待文件IO线程执行完毕,并且从挂起点恢复执行foo函数。promise_type可以用于自定义协程自身行为,代码的编写者可以自定义协程的多种状态以及自定义协程中任何co_await、co_return或co_yield表达式的行为,比如挂起前和恢复后的处理、如何返回最终结果等。否则返回false。

2023-04-25 14:19:41 368

原创 现代C++语言核心特性解析part16

读者一定写过无状态的类,这种类不需要有数据成员,唯一需要做的就是实现一些必要的函数,常见的是STL中一些算法函数所需的函数对象(仿函数)。carries_dependency是C++11标准引入的属性,该属性允许跨函数传递内存依赖项,它通常用于弱内存顺序架构平台上多线程程序的优化,避免编译器生成不必要的内存栅栏指令。在上面的例子中,attr1声明了对象a和b,attr2声明了类型X,X的属性也会影响到对象a和b,最后attr3只声明了对象b。(,),这是告诉编译器这个逗号是可选的。

2023-04-24 16:44:15 229

原创 现代C++语言核心特性解析part14

和int q = p +f();相反,std::is_constant_ evaluated() == true时,q的结果会依赖p,所以明显常量求值的结论显然不成立,需要采用std::is_constant_evaluated() == false的方案,于是f()函数中的m为17,最终q的求值结果是56。当函数实参为int时,std::is_same<T, std::string>::value和T::npos == −1都会被编译,由于int::npos显然是一个非法的表达式,因此会造成编译失败。

2023-04-24 13:19:57 141

原创 现代C++语言核心特性解析part13

C++11标准确定之前,各个编译器也用了自定义的方法支持线程局部存储。比如gcc和clang添加了关键字__thread来声明线程局部存储变量,而Visual Studio C++则是使用__declspec(thread)。在C++11标准中正式添加了新的thread_local说明符来声明线程局部存储变量。thread_local说明符可以用来声明线程生命周期的对象,它能与static或extern结合,分别指定内部或外部链接,不过额外的static并不影响对象的生命周期。被thread_local声

2023-04-18 14:12:39 78

原创 现代C++语言核心特性解析part12

3.类型T必须存在合法的成员函数模板get< i >()或者函数模板get< i >(t),其中i是小于std::tuple_size< T >::value的整数,t是类型T的实例,get< i >()和get< i >(t)返回的是实例t中第i个元素的值。2.类型T还需要保证std::tuple_element::type也是一个符合语法的表达式,其中i是小于std::tuple_size< T >::value的整数,表达式代表了类型T中第i个元素的类型。其次,这些数据成员必须是公有的;

2023-04-17 16:26:54 220

原创 现代C++语言核心特性解析part10

以上代码的方案1,利用的技巧是数组的大小不能为负值,当expr表达式返回结果为false的时候,条件表达式求值为−1,这样就导致数组大小为−1,自然就会引发编译失败。而方案3则声明了一个变量,可以出现在结构体和类的定义中,但是它最大的问题是会改变结构体和类的内存布局。在上面的代码中,if和else if都有初始化语句,它们分别初始化变量b和b1并且在各自条件成立的作用域内执行了日志输出。在上面的代码中,bool b = foo()是一个初始化语句,在初始化语句中声明的变量b能够在if的作用域继续使用。

2023-04-17 13:54:20 134

原创 现代C++语言核心特性解析part9

隐藏是指基类成员函数,无论它是否为虚函数,当派生类出现同名函数时,如果派生类函数签名不同于基类函数,则基类函数会被隐藏。for(auto n : x)的循环调用10次复制构造函数,如果类X的数据量比较大且容器里的元素很多,那么这种复制的代价是无法接受的。C++11标准提供了一个非常实用的override说明符,这个说明符必须放到虚函数的尾部,它明确告诉编译器这个虚函数需要覆盖基类的虚函数,一旦编译器发现该虚函数不符合重写规则,就会给出错误提示。final说明符不仅能声明虚函数,还可以声明类。

2023-04-17 12:44:17 143

原创 现代C++语言核心特性解析part8

C++17标准对聚合类型的定义做出了大幅修改,即从基类公开且非虚继承的类也可能是一个聚合。同时聚合类型还需要满足常规条件。1.没有用户提供的构造函数。2.没有私有和受保护的非静态数据成员。3.没有虚函数。在新的扩展中,如果类存在继承关系,则额外满足以下条件。4.必须是公开的基类,不能是私有或者受保护的基类。5.必须是非虚继承。

2023-04-17 11:26:52 163

原创 现代C++语言核心特性解析part7

基类Base的SomeFunc无法满足当前的业务需求,于是在其派生类Derived中重写了这个函数,但令人头痛的是,面对Base中大量的构造函数,我们不得不在Derived中定义同样多的构造函数,目的仅仅是转发构造参数,因为派生类本身并没有需要初始化的数据成员。4.委托构造函数的执行顺序是先执行代理构造函数的初始化列表,然后执行代理构造函数的主体,最后执行委托构造函数的主体。委托模板构造函数是指一个构造函数将控制权委托到同类型的一个模板构造函数,简单地说,就是代理构造函数是一个函数模板。

2023-04-14 13:19:18 98

原创 现代C++语言核心特性解析part6

第10章 默认和删除函数(C++11)10.1 类的特殊成员函数在没有自定义构造函数的情况下,编译器会为类添加默认的构造函数。像这样有特殊待遇的成员函数一共有6个(C++11以前是4个),具体如下。1.默认构造函数。2.析构函数。3.复制构造函数。4.复制赋值运算符函数。5.移动构造函数(C++11新增)。6.移动赋值运算符函数(C++11新增)。程序员可以有更多精力关注类本身的功能而不必为了某些语法特性而分心,同时也避免了让程序员编写重复的代码#include <string&g

2023-04-13 15:01:43 211

原创 现代C++语言核心特性解析part4

以及。

2023-04-13 10:43:59 171 2

原创 现代C++语言核心特性解析part3

左值和右值的概念早在C++98的时候就已经出现了,从最简单的字面理解,无非是表达式等号左边的值为左值,而表达式右边的值为右值,比如:但是还是过于简单,有些情况下是无法准确区分左值和右值的,比如:在第一行代码中a是左值,1是右值;在第二行代码中b是左值,而a是右值。在C++中所谓的左值一般是指一个指向特定内存的具有名称的值(具名对象),它有一个相对稳定的内存地址,并且有一段较长的生命周期。而右值则是不指向稳定内存地址的匿名值(不具名对象),它的生命周期很短,通常是暂时性的。基于这一特征,我们可以用取地址

2023-04-12 16:36:39 278

原创 现代C++语言核心特性解析part1

开发一个大型工程必然会有很多开发人员的参与,也会引入很多第三方库,这导致程序中偶尔会碰到同名函数和类型,造成编译冲突的问题。foo();C++11标准增强了命名空间的特性,提出了内联命名空间的概念。} 结果: Child1 :: foo() Child2 :: foo()该特性可以帮助库作者无缝升级库代码,让客户不用修改任何代码也能够自由选择新老库代码。# include <iostream> //升级前: namespace Parent {

2023-04-12 10:22:23 495 1

原创 现代C++语言核心特性解析part2

严格来说auto并不是一个新的关键字,因为它从C++98标准开始就已经存在了。当时auto是用来声明自动变量的。C++11标准赋予了auto新的含义:声明变量时根据初始化表达式自动推断该变量的类型、声明函数时函数返回值的占位符。auto i = 5;// 推断为int auto str = "hello auto";// 推断为const char* auto sum(int a1 , int a2) -> int // 返回类型后置,auto为返回值占位符 {

2023-04-12 10:21:45 261 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除