周记 2020.01.06-01.12
最近的生活也算是走上正轨,但却好像抽不出时间写周记。这是不好的,因为就算再忙,也要知道我在忙什么,不然可能会很危险的。
姑且把上周写的一些C++笔记当作周记吧,毕竟也是涵盖了上周的大部分活动。
预处理
预处理功能有三种:宏定义,文件包含和条件编译
条件编译
#ifndef
与#endif
配套使用
1 |
|
这是条件编译的意思
1 |
|
所以我在vs代码中看到的,只是为了满足不同的编译器。
一些概念
Q:.hpp与.h的区别
A:.h只有声明没有实现,.hpp既有声明又有实现
Q:用VS编译(GCC编译没有这个事),为什么会找不到标识符,明明IDE说的变量在错误行根本没有,而且变量已经定义了
Q:delete
与delete[]
的区别
A:目前我的理解是,对于类,上述两者有区别,对于普通类型变量没有区别。但我现在面对的是结构体中的变量…怎么办…
C++标准
C++11正式引入了多线程的概念,直到现在,仍能看到指定基于C++11标准进行编译的项目。我现在的用VS2019,似乎默认基于C++14标准编译。现在也开始接触C++17的一些函数。
编译的经验
从在CentOS上编译caffe开始,到后来在Windows下编译av1,再到现在。
1.版本限定
在用Python装一些依赖库的时候,就会遇到不仅有版本下限的要求,还会有版本上限的要求。
我在这段时间编译vs plugin时,作为接口的头文件,要与自用的vs保持一致,用更高版本的也不行,vseditor无法识别。
又比如,编译C++ API的TensorFlow,似乎所需的proto要和TensorFlow版本一致,高低都不行,这和上面vs的情况很类似。
直到现在,还会觉得编译是个让人头疼的问题。不过头疼是面对向TensorFlow这样我不熟悉的代码时;而我熟悉的vs,虽然搞明白版本依赖也是踩坑之后才想明白的,但因为熟悉,很快就接受并习以为常了。
所以,“人和人真不是相通的”,很多时候我自己写的笔记,我可以肯定很多人会看不明白,因为这是写给我自己的。相应的,其实很多体量已经很庞大的项目,那些Doc也未必适合初学者,不理解是正常的。而每个人的机器不一样,空机器还好;一台用了很久的机器,潜在的依赖不知道是什么样。自己编译源码时出现问题,更是很正常的。
2.在Windows下像Linux一样编译
小标题现在看来像是一句正确的废话。但很长一段时间以来的我,都以Linux有着独特“优势”。这话说出来,看上去没什么错,但我的理解有问题。直到用了Visual Studio的Developer Command Prompt和MSVC,用了cmake,我才知道,原来Windows下也能这么编译。而Linux所谓的优势,或许是更便捷,而并非“专属”。
3.复杂依赖的解决
或者更具体点,复杂头文件的解决。
起初我编译自己写的vs plugin,所需的头文件很少,直接copy到工程目录也不是事。之后学OpenCV,被教程惯坏了,照着书本一通配置库目录,然后就能无脑敲代码了。
其实很简单的逻辑关系,我挺早的时候就弄明白了,依赖的无非就是头文件和库文件。但依赖一多,比如我编译基于ncnn写的代码的时候,一堆依赖,再用复制大法..恐怕也不行…
所以老老实实地配环境,配目录吧。(话说MSVC还有x64.props
和Win32.props
,读取用户器件上的依赖,避免了版本不匹配的问题)
4.从GCC到指令集优化
话说我很喜欢写“从…到…”的句式。因为要补的东西太多,往往遇见一个新东西就能启发到另一个东西。
在64位的GCC目录下,藏着这么个东西,immintrin.h
。
1 |
|
immintrin.h
集成了AVX指令集优化的相关头文件,是打开指令集优化大门的撬棍。我心念念的指令集优化终于有了着落。
人生相谈
在NGA论坛看到的,值得好好读一下。
gcc和msvc等编译工具要熟悉,make file要会写。