C/C++使用指南
auto:for(auto& name : input){}
c++中name mingling较C更为复杂
创建静态链接库
gcc -fPIC -c a.c
gcc -fPIC -c b.c
gcc -shared -o libfoo.so a.o b.o
创建动态链接库
gcc -c a.c
gcc -c b.c
gcc -c main.c
ar cr libfoo.a a.o b.o
gcc main.o libfoo.a
链接:
-L [.] #添加搜索目录
-l[a] #链接liba.so
g++ -o temp ./main.so ./libb.so ./liba.so #首先查找libb,然后查找liba
alignas(64) int array[1024]; // 以64对齐内存
-l[lib]
选项需要在 cpp 文件后面(链接器从前向后处理,只从每个 lib 中提取当前需要的符号函数 见链接)-isystem [dir]
将 [dir]
指定为和系统 include,查找 include 顺序为 -I
目录,-isystem
目录,系统 include 目录
restrict关键字,告知编译器不存在指针aliasing
如:
void example2b(float * __restrict__ a, float * __restrict__ b, float * __restrict__ c) {
for (int i = 0; i < 1024; i++) {
a[i] = 0.0f;
b[i] = 0.0f;
for (int j = 0; j < 1024; j++) {
a[i] = a[i] + c[i<em>1024 + j];
b[i] = b[i] + c[i</em>1024 + j] * c[i*1024 + j];
}
}
}
告知编译器a,b,c三数组内容不重合
在cuda中,只有当指针标记为 const, restrict 时,cuda编译器才会认为数组为只读内容,并使用read-only cache对其优化
C++11 && C++14 特性
SFINAE (substitution-failure-is-not-an-error) 原则:在模板中执行替换时解析错误不认为是错误,而是忽略该模板
#include <iostream>
using namespace std;
void f(double a){
cout<<"in double f()"<<endl;
}
template<typename T>
void f(typename T::noexist a){
cout<<"in T::noexist f()"<<endl;
}
int main(){
f(1);
f(1.0);
}
此时 f(0)
和 f(1.0)
均调用 f(double a)
typename std::enable_if<(std::is_same<T, float>::value)>::type
当 T 为 float 时为 void type,否则解析失败
模板
typename
用于在模板中表示一个东西是类型decltype
用于推导表达式的类型
template <typename T>
class MyClass {
public:
typename T::value_type member; // 'typename' specifies that T::value_type is a type
auto getMember() -> decltype(member) {
return member; // 'decltype' deduces the return type of the function based on 'member'
}
};
std::same
用于在编译时比较类型
if (std::is_same<typename DoCoul<PairStyle::COUL_FLAG>::type, CoulTag>::value) {
printf("ERROR: DoCoul<PairStyle::COUL_FLAG>::type is CoulTag\n");
exit(1);
}
数组指针:int p[4]
: p为大小为4数组,其中每个元素为指向 int 指针。 [] 优先级高于 , 解析为 (int*) (p[4])
int (*p)[4]
: p为单个指针,指向 大小为 4 的 int 数组,初始化可以直接使用 p = new int8
宏定义:#define PRINTCLASS(ClassName) printout(#ClassName)
: #ClassName
传入参数转换为字符串 #define DeclareSomething(ArgumentName,i) int ArgumentName##i
: ##
用于连接两个单元#define Declare_Fun(...) typedef std::function<void(__VA_ARGS__)> iStdFunction
: ...
为可变参数,用 VA_ARGS
获取
gcc -E m.cpp -o m.i
: 预编译,m.i 为宏展开结果
编译与链接
-m
: x86 相关选项 -march=native
: 生成针对本机优化的代码-mcmodel=large
: 可以开超过 2G 的全局数组
include 文件在编译时直接使用对应文件替换 include 语句#include "filename"
首先在源文件路径搜索目标头文件,然后搜索默认路径#include <filename>
搜索默认路径
cpp : c pre-processor 负责头文件查找和替换cpp -v
显示头文件查找路径-Wl,param1,param2,...
: 编译时传给ld链接器的参数
c/c++ mocking function : -Wl,--wrap=[func]
对 func
进行 mock,调用 func
函数时会尝试调用 __wrap_func
,使用 __read_func
调用原 func
函数
想想你的文章写的特别好https://www.237fa.com/