宏
宏函数
自增,自减(考虑了锁
1 | _MT_INCR(a); |
关键字
restrict
作用一: 告诉编译器,编译器可以根据这个大胆做优化
1 | void test() |
对于ptr指针,编译器会优化成ptr += (2+3);一条语句。但是tmp这个指针就不能优化成tmp += 3,因为可能这个地址会通过a来修改。
需要注意的是,这个只是约定而已,如果你加了这个restrict限定,那么需要有程序员保证这一规则的成立,也就是说,即使你用一个新的指针指向ptr,然后通过这个指针修改内容,编译器也不会报错。但是可能就没有优化效果了。(未看汇编证实,后续证实)
作用二:告诉程序员,这段内存需要满足restrict规则
C库中有两个函数可以从一个位置把字节复制到另一个位置。在C99标准下,它们的原型如下:
1 | void * memcpy(void * restrict s1, const void * restrict s2, size_t n); |
这两个函数均从s2指向的位置复制n字节数据到s1指向的位置,且均返回s1的值。两者之间的差别由关键字restrict造成,即memcpy函数内部可以假定两个内存区域没有重叠,但是需要使用者来保证,如果没有按照规则,则内部的实现如果没有考虑重叠的情况,就可能出问题。memmove()函数则不做这个假定,因此,复制过程类似于首先将所有字节复制到一个临时缓冲区,然后再复制到最终目的地。同样,编译器并不会对这个做检测,你告诉编译器什么,编译器就相信什么了。
1 | void test() |
如上面的代码,tmp初始指向字符‘l’,按照本意,我们是想把从ptr开始的5个字符“Hello”复制到从tmp开始的地址上。那么如果memcpy没有考虑地址重叠的话,它会从ptr开始把字符一个一个拷贝到tmp地址上。那么你就会发现,当把第一个字符“H”拷贝到tmp指向’l’的位置的时候,被拷贝的5个字符已经变成“HelHo”了,也就是改dst的同时,也改到了src了。那这样起来肯定会违背我们的本意,但是这个不是memcpy的锅,人家已经通过restrict告诉你s2这块地址只有限定在只能通过s2指针来访问才能保证没问题,是你自己没按照函数规则来。
这也告诉我们,在设计memcpy的时候,需要考虑这种情况。解决办法如下,当修改dst也有可能改到src的情况下,可以把src和dst均加上要拷贝的size,然后从尾巴开始逐一字符拷贝,这样就不会有重叠了。
模板
可变模版参数
#define EXPAND(x) x这个宏的作用不是很明白…但是必须用…
另外此如果超过了9个数,并不会报错..
1 |
lambda
捕获
1 | 捕获列表的形式为"[=]"(值捕获)或者"[&]"(引用捕获); |
杂项
获取结构体在堆中的偏移量
e.g.在封装d3d12提及资源时,gpu使用CreateCommittedResource分配好堆,要查询该堆中变量的数据,需要查询index.
1 |