Skip to content

Commit

Permalink
56 fix #5
Browse files Browse the repository at this point in the history
  • Loading branch information
wanghenshui committed Apr 2, 2022
1 parent fb29f72 commit 558a000
Show file tree
Hide file tree
Showing 2 changed files with 347 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ RSS使用仓库的release RSS [链接](https://github.com/wanghenshui/cppweeklyn
| [二十一](./posts/021.md) | [二十二](./posts/022.md) | [二十三](./posts/023.md) | [二十四](./posts/024.md) | [二十五](./posts/025.md) | [二十六](./posts/026.md) | [二十七](./posts/027.md) | [二十八](./posts/028.md) | [二十九](./posts/029.md) | [三十期](./posts/030.md) |
| [三十一](./posts/031.md) | [三十二](./posts/032.md) | [三十三](./posts/033.md) | [三十四](./posts/034.md) | [三十五](./posts/035.md) | [三十六](./posts/036.md) | [三十七](./posts/037.md) | [三十八](./posts/038.md) | [三十九](./posts/039.md) | [四十期](./posts/040.md) |
| [四十一](./posts/041.md) | [四十二](./posts/042.md) | [四十三](./posts/043.md) | [四十四](./posts/044.md) | [四十五](./posts/045.md) | [四十六](./posts/046.md) | [四十七](./posts/047.md) | [四十八](./posts/048.md) | [四十九](./posts/049.md) | [五十期](./posts/050.md) |
| [五十一](./posts/051.md) | [五十二](./posts/052.md) | [五十三](./posts/053.md) | [五十四](./posts/054.md)| [五十五](./posts/055.md) | | | | | |
| [五十一](./posts/051.md) | [五十二](./posts/052.md) | [五十三](./posts/053.md) | [五十四](./posts/054.md)| [五十五](./posts/055.md) | [五十六](./posts/056.md) | | | | |



Expand Down
346 changes: 346 additions & 0 deletions posts/056.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,346 @@
---
layout: post
title: 第56期
---

# C++ 动态新闻推送 第56期

[reddit](https://www.reddit.com/r/cpp/)/[hackernews](https://news.ycombinator.com/)/[lobsters](https://lobste.rs/)/[meetingcpp](https://www.meetingcpp.com/blog/blogroll/items/Meeting-Cpp-Blogroll-323.html/)摘抄一些c++动态

[周刊项目地址](https://github.com/wanghenshui/cppweeklynews)[在线地址](https://wanghenshui.github.io/cppweeklynews/)[知乎专栏](https://www.zhihu.com/column/jieyaren) |[腾讯云+社区](https://cloud.tencent.com/developer/column/92884)

弄了个qq频道,[手机qq点击进入](https://qun.qq.com/qqweb/qunpro/share?_wv=3&_wwv=128&inviteCode=xzjHQ&from=246610&biz=ka)

欢迎投稿,推荐或自荐文章/软件/资源等,请[提交 issue](https://github.com/wanghenshui/cppweeklynews/issues)

最近非常忙,cppcon的视频没怎么看。更新也有拖延,见谅

---

## 资讯

标准委员会动态/ide/编译器信息放在这里

[编译器信息最新动态推荐关注hellogcc公众号 本周更新 第143期](https://github.com/hellogcc/osdt-weekly/blob/master/weekly-2022/2022-03-30.md)

## 文章

- [chibicc——可能是可读性最强的 C 编译器](https://zhuanlan.zhihu.com/p/490307409)

一个读编译器源码的大纲,可以看看

- [如何设计一个C++的类](https://zhuanlan.zhihu.com/p/271732707)

其实是api设计理念的问题。哎。工作踩坑才会明白



- [Converting integers to decimal strings faster with AVX-512](https://lemire.me/blog/2022/03/28/converting-integers-to-decimal-strings-faster-with-avx-512/)

[Daniel Lemire](https://lemire.me/blog/)博士老活,还是那个数组转字符串最快的问题,如何用avx实现

```c++
void to_string_avx512ifma(uint64_t n, char *out) {
uint64_t n_15_08 = n / 100000000;
uint64_t n_07_00 = n % 100000000;
__m512i bcstq_h = _mm512_set1_epi64(n_15_08);
__m512i bcstq_l = _mm512_set1_epi64(n_07_00);
__m512i zmmzero = _mm512_castsi128_si512(_mm_cvtsi64_si128(0x1A1A400));
__m512i zmmTen = _mm512_set1_epi64(10);
__m512i asciiZero = _mm512_set1_epi64('0');

__m512i ifma_const = _mm512_setr_epi64(0x00000000002af31dc, 0x0000000001ad7f29b,
0x0000000010c6f7a0c, 0x00000000a7c5ac472, 0x000000068db8bac72, 0x0000004189374bc6b,
0x0000028f5c28f5c29, 0x0000199999999999a);
__m512i permb_const = _mm512_castsi128_si512(_mm_set_epi8(0x78, 0x70, 0x68, 0x60, 0x58,
0x50, 0x48, 0x40, 0x38, 0x30, 0x28, 0x20, 0x18, 0x10, 0x08, 0x00));
__m512i lowbits_h = _mm512_madd52lo_epu64(zmmzero, bcstq_h, ifma_const);
__m512i lowbits_l = _mm512_madd52lo_epu64(zmmzero, bcstq_l, ifma_const);
__m512i highbits_h = _mm512_madd52hi_epu64(asciiZero, zmmTen, lowbits_h);
__m512i highbits_l = _mm512_madd52hi_epu64(asciiZero, zmmTen, lowbits_l);
__m512i perm = _mm512_permutex2var_epi8(highbits_h, permb_const, highbits_l);
__m128i digits_15_0 = _mm512_castsi512_si128(perm);
_mm_storeu_si128((__m128i *)out, digits_15_0);
}


void to_string_tree_table(uint64_t x, char *out) {
static const char table[200] = {
0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35,
0x30, 0x36, 0x30, 0x37, 0x30, 0x38, 0x30, 0x39, 0x31, 0x30, 0x31, 0x31,
0x31, 0x32, 0x31, 0x33, 0x31, 0x34, 0x31, 0x35, 0x31, 0x36, 0x31, 0x37,
0x31, 0x38, 0x31, 0x39, 0x32, 0x30, 0x32, 0x31, 0x32, 0x32, 0x32, 0x33,
0x32, 0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37, 0x32, 0x38, 0x32, 0x39,
0x33, 0x30, 0x33, 0x31, 0x33, 0x32, 0x33, 0x33, 0x33, 0x34, 0x33, 0x35,
0x33, 0x36, 0x33, 0x37, 0x33, 0x38, 0x33, 0x39, 0x34, 0x30, 0x34, 0x31,
0x34, 0x32, 0x34, 0x33, 0x34, 0x34, 0x34, 0x35, 0x34, 0x36, 0x34, 0x37,
0x34, 0x38, 0x34, 0x39, 0x35, 0x30, 0x35, 0x31, 0x35, 0x32, 0x35, 0x33,
0x35, 0x34, 0x35, 0x35, 0x35, 0x36, 0x35, 0x37, 0x35, 0x38, 0x35, 0x39,
0x36, 0x30, 0x36, 0x31, 0x36, 0x32, 0x36, 0x33, 0x36, 0x34, 0x36, 0x35,
0x36, 0x36, 0x36, 0x37, 0x36, 0x38, 0x36, 0x39, 0x37, 0x30, 0x37, 0x31,
0x37, 0x32, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35, 0x37, 0x36, 0x37, 0x37,
0x37, 0x38, 0x37, 0x39, 0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x33,
0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37, 0x38, 0x38, 0x38, 0x39,
0x39, 0x30, 0x39, 0x31, 0x39, 0x32, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35,
0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39,
};
uint64_t top = x / 100000000;
uint64_t bottom = x % 100000000;
uint64_t toptop = top / 10000;
uint64_t topbottom = top % 10000;
uint64_t bottomtop = bottom / 10000;
uint64_t bottombottom = bottom % 10000;
uint64_t toptoptop = toptop / 100;
uint64_t toptopbottom = toptop % 100;
uint64_t topbottomtop = topbottom / 100;
uint64_t topbottombottom = topbottom % 100;
uint64_t bottomtoptop = bottomtop / 100;
uint64_t bottomtopbottom = bottomtop % 100;
uint64_t bottombottomtop = bottombottom / 100;
uint64_t bottombottombottom = bottombottom % 100;
//
memcpy(out, &table[2 * toptoptop], 2);
memcpy(out + 2, &table[2 * toptopbottom], 2);
memcpy(out + 4, &table[2 * topbottomtop], 2);
memcpy(out + 6, &table[2 * topbottombottom], 2);
memcpy(out + 8, &table[2 * bottomtoptop], 2);
memcpy(out + 10, &table[2 * bottomtopbottom], 2);
memcpy(out + 12, &table[2 * bottombottomtop], 2);
memcpy(out + 14, &table[2 * bottombottombottom], 2);
}

```
avx版本要比大表快四倍,我没有编译验证,有空可以贴googlebenchmark跑一下
- [Automatic Serialization in C++ for Game Engines](https://indiegamedev.net/2022/03/28/automatic-serialization-in-cpp-for-game-engines/)
用宏来反射。不多说
- [[RFC\] Lifetime annotations for C++](https://discourse.llvm.org/t/rfc-lifetime-annotations-for-c/61377)
llvm考虑引入生命周期标记,这是整体设计文档
- [gcc 10, 11 std::span ABI break](https://www.reddit.com/r/cpp/comments/ttpe1p/gcc_10_11_stdspan_abi_break/)
注意span使用,内存布局不同
- [Storing references of pointers in containers in C++](https://www.sandordargo.com/blog/2022/03/30/vector-of-references-of-pointers)
别用数组存指针,用boost::ptr_vector
别用数组存指针,局部性非常差
- [Software Design with Traits and Tag Dispatching](http://www.modernescpp.com/index.php/softwaredesign-with-traits-and-tag-dispatching)
古老技术
```c++
#include <iterator>
#include <forward_list>
#include <list>
#include <vector>
#include <iostream>
template <typename InputIterator, typename Distance>
void advance_impl(InputIterator& i, Distance n, std::input_iterator_tag) {
std::cout << "InputIterator used" << '\n';
while (n--) ++i;
}
template <typename BidirectionalIterator, typename Distance>
void advance_impl(BidirectionalIterator& i, Distance n, std::bidirectional_iterator_tag) {
std::cout << "BidirectionalIterator used" << '\n';
if (n >= 0)
while (n--) ++i;
else
while (n++) --i;
}
template <typename RandomAccessIterator, typename Distance>
void advance_impl(RandomAccessIterator& i, Distance n, std::random_access_iterator_tag) {
std::cout << "RandomAccessIterator used" << '\n';
i += n; // (5)
}
template <typename InputIterator, typename Distance> // (4)
void advance_(InputIterator& i, Distance n) {
typename std::iterator_traits<InputIterator>::iterator_category category;
advance_impl(i, n, category);
}
int main(){
std::cout << '\n';
std::vector<int> myVec{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // (1)
auto myVecIt = myVec.begin();
std::cout << "*myVecIt: " << *myVecIt << '\n';
advance_(myVecIt, 5);
std::cout << "*myVecIt: " << *myVecIt << '\n';
std::cout << '\n';
std::list<int> myList{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // (2)
auto myListIt = myList.begin();
std::cout << "*myListIt: " << *myListIt << '\n';
advance_(myListIt, 5);
std::cout << "*myListIt: " << *myListIt << '\n';
std::cout << '\n';
std::forward_list<int> myForwardList{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // (3)
auto myForwardListIt = myForwardList.begin();
std::cout << "*myForwardListIt: " << *myForwardListIt << '\n';
advance_(myForwardListIt, 5);
std::cout << "*myForwardListIt: " << *myForwardListIt << '\n';
std::cout << '\n';
}
```



- [C++23 Will Be Really Awesome](https://www.kdab.com/cpp23-will-be-really-awesome/)

介绍c++23强类型带来的优势

- [**Did you know that C++20 added support for floating point values as non-type template parameters?** ](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/271.md/)

```c++
emplate<double Value> constexpr auto value = Value;

int main() {
std::cout << value<4.2>; // prints 4.2
}
```

以前只支持整数,现在浮点数也可以了(有啥用???????? )

- [`saturating_add` vs. `saturating_int` – new function vs. new type?](https://www.foonathan.net/2022/03/behavior-function-type/)

实现一个能处理溢出的整型,实现一个函数好还是实现一个新类型好?想象int和std::atomic\<int>

- [Working with Strings in Embedded C++](https://blog.feabhas.com/2022/02/working-with-strings-in-embedded-c/)

嵌入式IoT环境 string选型,std::string想用用不了,std::pmr::string想用用不了 string_view可以用

- [C++20 Ranges: The Key Advantage - Algorithm Composition ](https://www.cppstories.com/2022/ranges-composition/)

range的算法要比以前的stl算法优雅,建议多用

比如

```c++
#include <algorithm>
#include <vector>
#include <iostream>

int main() {
const std::vector numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

auto even = [](int i) { return 0 == i % 2; };

std::vector<int> temp;
std::copy_if(begin(numbers), end(numbers), std::back_inserter(temp), even);
std::vector<int> temp2(begin(temp)+1, end(temp));

for (auto iter = rbegin(temp2); iter!=rend(temp2); ++iter)
std::cout << *iter << ' ';
}

```



range

```c++
#include <algorithm>
#include <vector>
#include <iostream>
#include <ranges> // new header!

int main() {
const std::vector numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

auto even = [](int i) { return 0 == i % 2; };

std::ranges::reverse_view rv{
std::ranges::drop_view {
std::ranges::filter_view{ numbers, even }, 1
}
};
for (auto& i : rv)
std::cout << i << ' ';;
}

```

明显range更好看



- [C and C++ coding style for best performance ](https://www.ibm.com/docs/en/aix/7.1?topic=implementation-c-c-coding-style-best-performance)

Int char short,尽可能用int

用char尽可能unsigned,(笔者注:不过最好标记出你到底用哪个。不同平台默认行为不同 arm默认unsigned x86默认signed)

尽可能用局部变量不用全局变量,如果用,拷贝一份拿过来用

业务场景能用二进制判定就不要用字符串判定,字符串很浪费

Good

```c
#define situation_1 1
#define situation_2 2
#define situation_3 3
int situation_val;

situation_val = situation_2;
. . .
if (situation_val == situation_1)
```

bad

```c
char situation_val[20];

strcpy(situation_val,"situation_2");
. . .
if ((strcmp(situation_val,"situation_1"))==0)
```
如果非要用string,尽量用fixed size封装结合mem\*算法使用,不要用str\*算法 会检查\0
## 视频
- [C++ Weekly - Ep 317 - Do You Really Understand Member Functions? ](https://www.youtube.com/watch?v=4etjb2_KAaE)
成员函数是怎么工作的,this指针能不能复制一份?
## 开源项目需要人手
- [asteria](https://github.com/lhmouse/asteria) 一个脚本语言,可嵌入,长期找人,希望胖友们帮帮忙,也可以加群384042845和作者对线
- [pika](https://github.com/OpenAtomFoundation/pika) 一个nosql 存储, redis over rocksdb,非常需要人贡献代码胖友们, 感兴趣的欢迎加群294254078前来对线
## 新项目介绍/版本更新
- [一个代码检测小工具,检查头文件](https://github.com/wqking/cpp-header-checker)
- [有哪些值得推荐的小型 C 语言开源项目?](https://www.zhihu.com/question/20792016/answer/2408343848)
## 工作招聘
- [腾讯)编译器高级研发工程师 (北京/上海/杭州/深圳)](https://mp.weixin.qq.com/s/DF-2qmHmpKZtJ1djHXM1Ug)
---
看到这里或许你有建议或者疑问或者指出错误,请留言评论! 多谢! 你的评论非常重要!也可以帮忙点赞收藏转发!多谢支持!
[本文永久链接](https://wanghenshui.github.io/cppweeklynews/posts/056.html)

0 comments on commit 558a000

Please sign in to comment.