C++
文章平均质量分 50
mo.xiaoming
这个作者很懒,什么都没留下…
展开
-
C++备忘录106:safe signed/unsigned comparison
C++中无符号数和有符号数的比较永远让人提心吊胆void foo() { int i = -1; unsigned j = 1; if (i > j) { // this branch is taken } else { // }C++20中,<utility>增加了比较函数,处理这种情况#include <utility>extern int i;extern unsigned j;bool unsafe() { return i原创 2021-05-26 09:37:20 · 313 阅读 · 0 评论 -
C++备忘录105:decltype() vs decltype(())
#include <type_traits>void foo(int&& i) { static_assert(std::is_same_v<decltype(i), int&&>); static_assert(std::is_same_v<decltype((i)), int&>);}i类型是右值引用,但是本身的value catagory是左值。但是直接decltype(i)的话,发现返回的永远是右原创 2021-05-25 12:15:48 · 228 阅读 · 0 评论 -
C++备忘录104:copy-swap idiom or not?
#include <utility>struct S { explicit S(std::size_t size) : buf_(new char[size]), size_(size) {} S(S const& other) : S(other.size_) {} S(S&& other) noexcept { swap(*this, other); } S& operator=(S const& other) &a原创 2021-05-23 22:40:10 · 215 阅读 · 0 评论 -
C++备忘录103:OOP best practices by Jon Kalb
Object-Oriented Program - Best Practices - Jon Kalb [ C++ on Sea 2020 ]C++ Coding Standards, Rule 38: “Practice safe overriding”After the base class guarantees the preconditions and postconditions of an operation, any derived class must respect those gu原创 2021-05-23 09:39:16 · 186 阅读 · 0 评论 -
C++备忘录102:Always Auto may have extra overhead
当有buffer随后会被覆盖,所以一开始的初始化没有意义的时候,要小心AAA带来的额外性能损耗auto s = S() without ctorstruct S { void foo();private: char buf[1024];};void foo() { auto s = S{}; // value initialization s.foo();}S中的buf此时会被初始化成全0值foo():原创 2021-05-22 09:40:28 · 116 阅读 · 0 评论 -
C++备忘录101:覆盖敏感数据的代码可能被优化掉
编译器会把它认为无用的代码移除,这在移除敏感数据时造成了麻烦,比如#include <algorithm>void get_pwd(char*);void store_pwd(char const*);void foo() { char buf[1024]; get_pwd(buf); store_pwd(buf); std::fill(buf, buf + sizeof(buf)/sizeof(buf[0]), 0);}汇编代码如下foo()原创 2021-05-21 22:24:40 · 136 阅读 · 0 评论 -
C++备忘录100:std::ssize终于来了
C++的经典问题#include <iostream>int main() { int a = -1; unsigned b = 1; std::cout << (a > b ? "-1 > 1" : ""); // prints -1 > 1}因为继承自C的整型转换规则,宽度相同的整数,有符号数被转换成无符号数,所以-1 > 1。这是不同符号数运算始终存在的风险为了避免这种问题,除了位运算之类的特殊操作,一切整型都应该使原创 2021-05-20 22:27:03 · 367 阅读 · 0 评论 -
C++备忘录099:useful gcc/clang builtin functions
位运算ffs(n)返回从右向左数第几位是1。n==0时返回0constexpr int ffs(int n) noexcept { return __builtin_ffs(n) - 1;}static_assert(ffs(0b11) == 0);static_assert(ffs(0b10) == 1);clz(n)返回前导0的个数。n==0时返回未定义constexpr int clz(unsigned n) noexcept { // clz: counting leading z原创 2021-05-06 23:59:21 · 358 阅读 · 0 评论 -
C++备忘录098:tips for low latency code
measure, measure, measuresimpler code is likely the faster codecompile time computation over runtimeuser-space code only, no system callscache warmingno memory allocation/deallocationno polymorphismno throwing exceptionskeep data/code of hot path .原创 2021-04-20 00:09:34 · 127 阅读 · 0 评论 -
C++备忘录097:std::sort vs qsort,always measure?
Carl Cook做过一个演讲,The Speed Game - Automated Trading Systems in C++ - Carl Cook - Meeting C++ 2016他提到C++中std::sort的性能超过C的qsort于是我在我的2012年的macbook pro上测了一下,使用apple clang -O3编译,得到了如下的结果2021-04-20T00:07:24+08:00Running ./bin/cpp-template_benchmarkRun on (原创 2021-04-20 00:08:43 · 120 阅读 · 0 评论 -
C++备忘录096:user-declared vs not-declared special member functions
Engineering Distinguished Speaker Series - Howard Hinnantuser-declaredstruct X { X() {} X(); X() = delete; X() = default;};not-declaredstruct X { template <typename ...T> X(T&& ... ts); // default ctor is n.原创 2021-04-16 21:49:26 · 113 阅读 · 0 评论 -
C++备忘录095:std::is_detected over inheritance
老的框架或库中经常可以见到这种继承关系struct B0 { virtual void walk() const = 0; virtual ~B0() = default;};struct B1 : B0 { virtual void fly() const = 0;};struct D0 : B1 { void fly() const override { fmt::print("D0::fly\n"); }; void walk() const ov原创 2021-04-15 23:40:55 · 263 阅读 · 0 评论 -
C++备忘录094:std::as_const prevents modifying captures
godbolt#include <utility>int main() { auto a = 3; [&a = std::as_const(a)] { a = 4; // error: cannot assign to a variable captured by copy in a non-mutable lambda }(); return a;}原创 2021-04-12 23:02:02 · 205 阅读 · 0 评论 -
C++备忘录093:“Do Not Return String Views to Strings“?
在《C++17 - The Complete Guide》中,提到class Person { std::string name;public: ... std::string_view getName() const { return name; }};// don’t do thisPerson createPerson();auto n = createPerson().getName(); // OOPS: deletes temporary stringstd::cou原创 2021-04-11 22:25:15 · 91 阅读 · 0 评论 -
C++备忘录092:简单的enum到string的方法?
godbolt#include <string_view>#include <algorithm>#include <type_traits>#include <fmt/core.h>#include <array>template <typename T>struct Enum { T val; std::string_view name; static constexpr std::stri原创 2021-04-10 14:11:54 · 634 阅读 · 0 评论 -
C++备忘录091:vector<int> or vector<vector<int>>?当编译器有不同意见时
c++17中,初始化时std::vector v1{42}; // vector<int>std::vector v2{v1}; // vector<int> not vector<vector<int>>std::vector v3 = v1; // vector<int>但是#include <vector>#include <type_traits>template <typename ...原创 2021-04-03 20:39:39 · 98 阅读 · 0 评论 -
C++备忘录090:__PRETTY_FUNCTION__
是gcc的扩展#include <cstdio>template <typename T>void foo(T) { puts(__PRETTY_FUNCTION__);}int main() { foo(4); foo(4.2); foo("Hello");}输出void foo(T) [with T = int]void foo(T) [with T = double]void foo(T) [with T = const原创 2021-04-03 10:45:08 · 470 阅读 · 1 评论 -
C++备忘录089:pthread_cancel doesn‘t go well with C++
以下对glibc为真pthread_cancel在C++中靠异常(abi::__forced_unwind)实现并且此异常必须rethrow,否则程序终止如果抛出点在nothrow函数中,程序终止macos下无此现象C++下不要用pthread_cancel,完毕原创 2021-03-10 21:35:21 · 110 阅读 · 0 评论 -
C++备忘录088:pimpl idiom by using std::unique_ptr
最近接触了stb库,非常有个性(被Windows逼的),实现和头文件都放在.h里,这就造成了一个限制:它的头文件只能include到.cpp里去,而不能出现在.hpp里(违反ODR)然后作者偏好C,于是api都是C风格的,也就是说资源需要我们自己释放以读取jpeg文件为例,分配资源的接口是unsigned char* stbi_load(char const* filename, int* width, int* height, int* channels, int N),然后返回的指针要通过stbi_原创 2021-02-25 00:03:07 · 130 阅读 · 0 评论 -
华为Atlas 200DK,几年后再见吧?
因为我像打不完的地老鼠一样不停的散布贬低甲方管理能力的负能量,甲方某人找我谈话的时候想拿华为的项目质量做对比。作为一个技术人员的我,回答说:“没接触过华为的项目,我不能做评价“。经过两个星期的折腾,现在我可以评价:“至少就Atlas 200DK来说,当前的项目质量是不能让人满意的“一步一坑编译重写的face-detection一步一坑Failed to import te.platform.log_util.按照"Atlas 200 DK 开发者套件(20.1)"文档的描述一步一步的去配置开发机原创 2021-01-10 21:50:55 · 3212 阅读 · 12 评论 -
C++备忘录087:std::is_convertible vs std::is_constructible
#include <type_traits>struct A {};struct B { B(A) {};};struct C { explicit C(A) {}};static_assert(std::is_constructible_v<B, A>);static_assert(std::is_convertible_v<A, B>);static_assert(std::is_constructible_v<C, A原创 2020-07-03 22:29:31 · 1117 阅读 · 0 评论 -
C++备忘录086:safe get by ref-qualifier
#include <fmt/core.h>struct S { std::string getValue() && { return std::move(value); } const std::string& getValue() const& { return value; }private: std::string value;};S foo() { return原创 2020-06-13 16:39:33 · 127 阅读 · 0 评论 -
C++备忘录085:reinterpret_cast/(Type*) is ok
不,它们不应该在代码里出现,除非你真的知道你在做什么,而不是自认为知道#include <cstdio>struct X { virtual void foo() { std::puts("X"); } ~X() = default;};struct Y { virtual void foo() { std::...原创 2020-03-29 10:54:01 · 142 阅读 · 0 评论 -
C++备忘录084:被gcc/clang支持的最常见的gnu扩展
Conditionals with Omitted Operandsx?:y 约等于 x?x:y,但前者x永远只被求值一次Case Rangescase 'A' ... 'Z':,小心空格Restricting Pointer Aliasingvoid fn (int *__restrict__ rptr, int &__restrict__ rref){ /* … */...原创 2020-03-29 10:09:39 · 147 阅读 · 0 评论 -
C++备忘录083:<cctype> sucks
C下<cctype>中的一堆操作字符的函数isupper,isalnum,toupper,它们的参数类型虽然都是int,但是如果传入char的话,是未定义行为Like all other functions from <cctype>, the behavior of std::isalnum is undefined if the argument’s value i...原创 2020-03-22 17:06:28 · 112 阅读 · 0 评论 -
C++备忘录082:智能指针管理其它资源
以fopen/fclose为例,直觉上是auto f1 = std::unique_ptr<FILE, int(*)(FILE*)>(std::fopen("a", "r"), std::fclose);它可以编译,gcc/clang不会给出任何警告,但至少这种写法是不可移植的。C++中因为overload的关系,不允许获取std函数的地址,所以更安全的写法是auto f2 =...原创 2020-03-21 19:49:52 · 151 阅读 · 0 评论 -
C++备忘录081:std::make_move_iterator, ugly but might be worthwhile
std::make_move_iterator把*iterator的返回值转换成右值,可以一定情况下把拷贝变成移动例如auto v1 = std::vector<std::string>(cbegin(v0), cend(v0));改成auto v1 = std::vector<std::string(std::make_move_iterator(begin(v0))...原创 2020-03-15 13:44:16 · 820 阅读 · 0 评论 -
C++备忘录080:C/C++中最让人恼火的特性
隐式类型转换#include <iostream>int main() { int a = -1; unsigned b = 1; if (a > b) { std::cout << "-1 > 1\n"; }}它打印-1 > 1,因为a与b的宽度一致,此时无符号数的优先级更高,a被根据numeric conversions规则转成...原创 2020-03-10 20:32:35 · 153 阅读 · 0 评论 -
C++备忘录079:小心构造函数抛出异常导致资源泄露
#include <iostream>#include <string>struct Y { Y() { std::cout << "Y()\n";} ~Y() { std::cout << "~Y()\n";}};struct S { S() { y1 = new Y{}; thr...原创 2020-03-07 12:39:05 · 107 阅读 · 0 评论 -
C++备忘录078:std::initializer_list sucks,big time
std::intializer_list always copies#include <iostream>#include <string>#include <vector>void* operator new(size_t s) { std::cout << s << '\n'; return malloc(s...原创 2020-03-07 11:10:11 · 126 阅读 · 0 评论 -
C++备忘录077:计算 set associative cache 对性能的影响
缓存的 N-way 可以通过getconf获取LEVEL1_ICACHE_SIZE 32768LEVEL1_ICACHE_ASSOC 8LEVEL1_ICACHE_LINESIZE 64LEVEL1_DCACHE_SIZE 32768LEVEL1_DCACHE_ASSOC...原创 2020-02-23 19:41:24 · 272 阅读 · 0 评论 -
C++备忘录076:新的就是好的,Small String Optimization
最近的接触的一个项目还在用gcc 4.8.5,除了这年月还在用C++98让我抓狂外,老编译也会带来无谓的性能上的损失,即使代码是完全一样的gcc 5之后增加了SSO的支持,当字符串长度不大于15的时候,不会进行动态内存分配,而是直接存储在std::string的结构体内#include <cstdlib>#include <iostream>void* opera...原创 2020-02-22 10:39:47 · 514 阅读 · 0 评论 -
C++备忘录075:alias shared_ptr
The aliasing constructor: constructs a shared_ptr which shares ownership information with the initial value of r, but holds an unrelated and unmanaged pointer ptr. If this shared_ptr is the last of t...原创 2020-02-16 17:03:05 · 142 阅读 · 0 评论 -
C++备忘录074:g++似乎要限制constexpr的处理深度
与vc和clang不同,gcc直到9.2似乎是对能否constexpr尝试到地老天荒的,但是刚刚偶然发现gcc(trunk)编译出来的代码与9.2不同了经典的斐波那契数列constexpr int fib(int n) { if (n==0) return 0; if (n==1) return 1; return fib(n-1) + fib(n-2);}int...原创 2020-02-15 10:03:30 · 377 阅读 · 0 评论 -
C++备忘录073:连续内存和顺序内存访问是效率之友,更显著的例子
受Destination: C++ Crash Course - Data Oriented Design启发对比的两者:传统的一个64字节长的类,然后用vector存储一堆这种类的对象一个大对象,其中每个成员对应传统类中一个成员的数组然后更新其中一个成员的所有值/所有成员的对应值即struct S { int v00; int v01; ;;;};vector<...原创 2020-02-12 13:49:55 · 235 阅读 · 0 评论 -
C++备忘录072:连续内存和顺序内存访问是效率之友
一个有一百万个字符的vector作为二维数组,bench_col首先从左到右,然后从上到下一行行的访问bench_row首先从上到下,然后从左到右一列列的访问其余所有的代码都一样,也就是说两个测试间实际上的不同只有 for (int r = 0; r < LENGTH / COLS; ++r) { for (int c = 0; c < COLS; ++c) {...原创 2020-02-11 21:20:13 · 283 阅读 · 0 评论 -
C++备忘录071:benchmark 说传参时perfect forwarding的效率一般最好,move相对copy是可以有额外代价的
struct foo { foo(paramType s) : s{s} {} std::string s;};perfect forwarding"最丑陋",但绝大多数情况下效率最高因为要处理源对象,所以在不涉及动态内存分配的情况下,相对单纯拷贝来说,移动的代价更高/*`c` for copy/create, `m` for move*_s_* passes a str...原创 2020-02-09 21:41:51 · 311 阅读 · 0 评论 -
C++备忘录070:benchmark 说传参时引用是好的
bench_copy,传参时拷贝,返回时NRVO auto const f = [inner](std::vector<int> v) -> std::vector<int> { for (int i = 0; i < inner; ++i) v.push_back(i); return v; // NRVO }; for (aut...原创 2020-02-09 20:13:36 · 359 阅读 · 0 评论 -
C++备忘录069:负数比正数大
int main() { int a = -1; unsigned b = 1; if (a <= b) { return 1; } else { return 0; // returns 0 }}这个不是未定义行为,任何符合标准的C++编译器都会返回0,这是因为numeric promotion规定了同...原创 2020-02-07 10:32:22 · 883 阅读 · 1 评论 -
C++备忘录068:Grouping google benchmark result
CppCon 2015 - Chandler Carruth ‘Tuning C++ - Benchmarks, and CPUs, and Compilers! Oh My!’听Chandler这个讲座的时候,google benchmark的输出看得我眼快瞎了bench_fastmod/16/32 176 ns 171 ns 397239...原创 2020-02-06 22:29:21 · 211 阅读 · 0 评论