周记 2020.01.06-01.12

最近的生活也算是走上正轨,但却好像抽不出时间写周记。这是不好的,因为就算再忙,也要知道我在忙什么,不然可能会很危险的。

姑且把上周写的一些C++笔记当作周记吧,毕竟也是涵盖了上周的大部分活动。

预处理

预处理功能有三种:宏定义,文件包含和条件编译

条件编译

#ifndef#endif配套使用

1
#if defined(__GNUC__) || defined(__clang__)

这是条件编译的意思

1
2
3
4
5
6
_WIN32    // Windows
__linux // Linux

__clang__ // Clang
__GNUC__ // GCC(需要注意的是Clang也会定义这个宏)
_MSC_VER // MSVC

所以我在vs代码中看到的,只是为了满足不同的编译器。

一些概念

Q:.hpp与.h的区别
A:.h只有声明没有实现,.hpp既有声明又有实现

Q:用VS编译(GCC编译没有这个事),为什么会找不到标识符,明明IDE说的变量在错误行根本没有,而且变量已经定义了

Q:deletedelete[]的区别
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.propsWin32.props,读取用户器件上的依赖,避免了版本不匹配的问题)

4.从GCC到指令集优化

话说我很喜欢写“从…到…”的句式。因为要补的东西太多,往往遇见一个新东西就能启发到另一个东西。

在64位的GCC目录下,藏着这么个东西,immintrin.h

1
mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include

immintrin.h集成了AVX指令集优化的相关头文件,是打开指令集优化大门的撬棍。我心念念的指令集优化终于有了着落。

人生相谈

在NGA论坛看到的,值得好好读一下。

gcc和msvc等编译工具要熟悉,make file要会写。

From: https://bbs.nga.cn/read.php?tid=19639952&page=2