从reddit/hackernews/lobsters/meetingcpp摘抄一些c++动态。
每周更新
欢迎投稿,推荐或自荐文章/软件/资源等,请提交 issue
介绍几种经典的分配器。这里的不是那种jemalloc那种插件式的,指的是内置型分配器
接上文,讨论了mimalloc的设计
讨论了函数传枚举怎样比较合适, 如果作为参数,有点类似bool flag hell那种问题,作者给了个放在模版参数的方案。比较清晰
没有最佳方案,封装成context结构体也可行,自己选择自己喜欢的写法
#include <iostream>
// Enum describing the mode used in the following function
enum class ChangeMode
{
Before,
After
};
// Function that squares a value and increases it (wether before or after), then prints the result
template<ChangeMode m>
void increase_and_square(int v)
{
if (m == ChangeMode::Before)
++v;
v = v*v;
if (m == ChangeMode::After)
++v;
std::cout << v << std::endl;
}
// main function
int main()
{
const int a = 42;
increase_and_square<ChangeMode::Before>(a);
increase_and_square<ChangeMode::After>(a);
}
手把手教你用rr调试(这个例子感觉用gdb也差不多)
讨论修订提案让decltype(auto) 尽可能的隐式move
手把手教你优化代码
std::vector<unsigned> LineOffsets;
LineOffsets.push_back(0);
const unsigned char *Buf = (const unsigned char *)Buffer.data();
const std::size_t BufLen = Buffer.size();
unsigned I = 0;
while (I < BufLen) {
if (Buf[I] == '\n') {
LineOffsets.push_back(I + 1);
} else if (Buf[I] == '\r') {
// If this is \r\n, skip both characters.
if (I + 1 < BufLen && Buf[I + 1] == '\n')
++I;
LineOffsets.push_back(I + 1);
}
++I;
}
\r\n出现的频率低,可以用unlikely
可以提前判定\r,加速,用memchr
memchr可以用bithack方法取代
最终patch在这里 https://reviews.llvm.org/D99409
讨论了一种代码场景
bool inRange(int val, int lo, int hi)
[[pre: lo <= hi]]
{
return (lo <= val && val <= hi);
}
注意参数是val lo hi,但是偶尔用错了,传参数传成了 lo val hi,这个逻辑就错了
如何解决这种问题?
一种方法是context
struct IntRange { int lo; int hi; };
bool inRange(int val, IntRange r);
assert(inRange({lower, upper}, existingValue)); // compile-time error
assert(inRange(existingValue, {lower, upper})); // OK
作者讨论语义问题,如何提供
return lo <= val <= hi
这种顺序的语义,把参数设定成这样是最好的设计,比如
std::rotate(first, new_first, last)
std::partial_sort(first, output_last, input_last)
std::nth_element(first, pos, last)
std::inplace_merge(first1, last1_also_first2, last2)
但是设计成inrange这种格式就很容易用错
比如std::clamp(value, lo, hi)
这个api作者觉得大概率是抄的opengl里的 接口
如何保证这种格式下,用错了接口,结果也是对的?用min max组合
int oneTrueClamp(int lo, int mid, int hi) {
return min(max(lo, mid), hi);
}
bool oneTrueInRange(int lo, int mid, int hi) {
return lo <= mid && mid <= hi;
}
这样mid/lo用错位置,结果也是相同的
这里其实是api设计哲学。这种知识有没有什么书有讲解的?
介绍了一系列Sanitizers ASAN MSAN UBSAN TSAN LSAN
手把手教你用catch2 测试库
觉得c++保持ABI不变过于保守,看向rust那种发展模式,多种abi都支持,并行
还是介绍json库,这个json库有insert_order的功能,这个json标准是不保证的
int main() {
{
nlohmann::json json{};
json["value"] = 42;
json["array"] = std::array{1, 2, 3};
std::cout << json.dump(); // prints {"array":[1,2,3],"value":42}
}
{
nlohmann::ordered_json json{};
json["value"] = 42;
json["array"] = std::array{1, 2, 3};
std::cout << json.dump(); // prints {"value":42", array":[1,2,3]}
}
}
gcc11新加了警告,能查出资源泄漏,如果分配释放不匹配就告警,比如fopen - fclose
讨论了if语句多少能影响到分支预测的性能,代码演示挺有意思的,可以本地玩一玩 代码在这里https://github.com/cloudflare/cloudflare-blog/blob/master/2021-05-branch-prediction