C++ 中文周刊 2024-01-19 第146期

2024-07-30 14:53:48 浏览数 (2)

RSS https://github.com/wanghenshui/cppweeklynews/releases.atom

欢迎投稿,推荐或自荐文章/软件/资源等

请留言

本期文章由 黄亮Anthony Amnisia HNY CHENL 赞助

上周和朋友们吃饭耽误了,一直没空写

资讯

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

编译器信息最新动态推荐关注hellogcc公众号 本周更新 2024-01-17 第237期

最近的最大热门就是Linux社区又有人讨论引入c 了,很多c宏实际上做的就是一部份concept工作,引入concept还是很爽的,不过linus有生之年应该不会引入,不过是又一次炒冷饭

祝linus健康

文章

The C 20 Naughty and Nice List for Game Devs https://www.jeremyong.com/c /2023/12/24/cpp20-gamedev-naughty-nice/)

介绍一些对游戏开发比较好的c 20特性

  • • <=> 不错
  • coroutine不错,可以用用这个 https://github.com/David-Haim/concurrencpp
  • std::bit_cast不错 复制转换,避免UB
  • <numbers>不错,有PI可以用了
  • • 新的同步原语 <barrier> <latch>``<semaphore>
  • <span>可以
  • • Designated initializers 非常好用,c一直都有,居然没兼容
代码语言:javascript复制

struct Point {
    float x;
    float y;
    float z;
};

Point origin{.x = 0.f, .y = 0.f, .z = 0.f};
代码语言:javascript复制

char8_t比较脑瘫,众所周知,char8_t是unsigned char,但u8 udl以前是修饰char的,c 20改成修饰char8_t了

破坏u8语义了,msvc可以/Zc:char8_t关掉,gcc也可以关 -fno-char8_t

https://en.cppreference.com/w/cpp/language/string_literal 第五条 六条 (5,6) UTF-8 string literal

const char[N](until C 20)

const char8_t[N](since C 20)

no_unique_address msvc有ABI问题,慎用

Modules没法用

ranges没屌用

format 二进制太大了

source_location 没易用性提升不说,std::source_location::file_name居然返回 const char*

怎么想的我真他妈服了

Why My Print Didnt Output Before a Segmentation Fault https://blog.yelinaung.com/posts/what-happened-to-my-print/
代码语言:javascript复制
#include <stdio.h>

int main(void)
{
        printf("%s", "Hello!");
        int *p = NULL;
        *p = 5;
        // Will not be reached due to crash above
        printf("%s", "Another Hello!");
}
//$ gcc -Wall -Wextra -o hello hello.c && ./hello
//Segmentation fault (core dumped)

经典buffer IO没刷buffer。怎么改成正常的?加n 用stderr用fflush

C time_point wackiness across platforms https://rachelbythebay.com/w/2024/01/01/chrono/

timepoint在mac上有精度损失,代码

代码语言:javascript复制
#include <stdio.h>

#include <chrono>

int main() {
  std::chrono::system_clock::time_point tp =
      std::chrono::system_clock::from_time_t(1234567890);

  // Okay.
  tp  = std::chrono::milliseconds(1);

  // No problem here so far.
  tp  = std::chrono::microseconds(1);

  // But... this fails on Macs:
  // tp  = std::chrono::nanoseconds(123);

  // So you adapt, and this works everywhere.  It slices off some of that
  // precision without any hint as to why or when, and it's ugly too!

  tp  = std::chrono::duration_cast<std::chrono::system_clock::duration>(
      std::chrono::nanoseconds(123));

  // Something like this swaps the horizontal verbosity for vertical
  // stretchiness (and still slices off that precision).

  using std::chrono::duration_cast;
  using std::chrono::system_clock;
  using std::chrono::nanoseconds;

  tp  = duration_cast<system_clock::duration>(nanoseconds(123));

  // This is what you ended up with:

  auto tse = tp.time_since_epoch();

  printf("%lldn", (long long) duration_cast<nanoseconds>(tse).count());

  // Output meaning when split up:
  //
  //        sec        ms  us  ns
  //
  // macOS: 1234567890 001 001 000  <-- 000 = loss of precision (246 ns)
  //
  // Linux: 1234567890 001 001 246  <-- 246 = 123   123 (expected)
  //

  return 0;
}
代码语言:javascript复制
Implementing the missing sign instruction in AVX-512 https://lemire.me/blog/2024/01/11/implementing-the-missing-sign-instruction-in-avx-512/

sign函数很常用, 大概长这样

代码语言:javascript复制
function sign(a, b): # a and b are integers
   if b == 0 : return 0
   if b < 0 : return -a 
   if b > 0 : return a
代码语言:javascript复制

很容易用sign实现abs

代码语言:javascript复制
abs(a) = sign(a,a)

进入正题,写一个avx512 sign

代码语言:javascript复制
#include <x86intrin.h>

__m512i _mm512_sign_epi8(__m512i a, __m512i b) {
  __m512i zero = _mm512_setzero_si512();
  __mmask64 blt0 = _mm512_movepi8_mask(b);
  __mmask64 ble0 = _mm512_cmple_epi8_mask(b, zero);
  __m512i a_blt0 = _mm512_mask_mov_epi8(zero, blt0, a);
  return _mm512_mask_sub_epi8(a, ble0, zero, a_blt0);;
}
代码语言:javascript复制

如果单独处理0场景,可以这样

代码语言:javascript复制
#include <x86intrin.h>

__m512i _mm512_sign_epi8_cheated(__m512i a, __m512i b) {
   __m512i zero = _mm512_setzero_si512();
  __mmask64 blt0 = _mm512_movepi8_mask(b);
  return _mm512_mask_sub_epi8(a, blt0, zero, a);;
}

/*
function sign_cheated(a, b): # a and b are integers
   if b < 0 : return -a 
   if b ≥ 0 : return a
*/
代码语言:javascript复制
[=What the func is that? https://biowpn.github.io/bioweapon/2024/01/18/what-the-func.html

c 26咱们有四个function了 std::function std::move_only_function std::copyable_function std::function_ref

都什么玩意?

std::function_ref好理解,就std::function的引用view版本,那他为啥不叫std::function_view?

另外两个是啥玩意?

回到function上,function的缺点是什么?看代码

代码语言:javascript复制
struct Functor {
    void operator()() { std::cout << "Non-constn"; }
    void operator()() const { std::cout << "Constn"; }
};

const Functor ftor;                   // I'm const!
const std::function<void()> f = ftor; // So am I! Const all the way
f();                                  // Prints "Non-const"
代码语言:javascript复制

问题就在于function的表现,复制Functor的时候,用的是值,自然用的是non const版本

这是缺陷!如何变成正常的样子?也就是这样

代码语言:javascript复制

代码语言:javascript复制
      std::function<void()> f = ftor; f(); // prints "Non-const"
const std::function<void()> f = ftor; f(); // prints "Const"
代码语言:javascript复制

为了修复这个const 问题,引入move_only_function 显然只能初始化一次

另外引入copyable_function 告诉大伙,function应该是copyable_function,大家注意语义

raymond chen环节,看不太懂

How do I prevent my C /WinRT implementation class from participating in COM aggregation? https://devblogs.microsoft.com/oldnewthing/20240108-00/?p=109250

In C /WinRT, how can I await multiple coroutines and capture the results?, part 1 https://devblogs.microsoft.com/oldnewthing/20240110-00/?p=109256

In C /WinRT, how can I await multiple coroutines and capture the results?, part 2 https://devblogs.microsoft.com/oldnewthing/20240111-00/?p=109259

In C /WinRT, how can I await multiple coroutines and capture the results?, part 3 https://devblogs.microsoft.com/oldnewthing/20240112-00/?p=109267

视频

Taro: Task Graph-Based Asynchronous Programming Using C Coroutine – Dian-Lun Lin - CppCon 2023 hhttps://www.youtube.com/watch?v=UCejPLSCaoI&ab_channel=CppCon

他这个设计就是taskflow的coroutine版本!说实话我之前想到过这个点子,但人家费心思实现了,我就想想

感兴趣的可以看这个仓库和视频

https://github.com/dian-lun-lin/taro

开源项目介绍

  • • asteria https://github.com/lhmouse/asteria 一个脚本语言,可嵌入,长期找人,希望胖友们帮帮忙,也可以加群753302367和作者对线
  • • Unilang https://github.com/linuxdeepin/unilang deepin的一个通用编程语言,点子有点意思,也缺人,感兴趣的可以github讨论区或者deepin论坛看一看。这里也挂着长期推荐了

一个完美hash库 https://github.com/boost-ext/mph

又一个hash表 https://github.com/SergeyMakeev/ExcaliburHash

他列举了一些场景,表现不过

catch2 3.5发布 https://github.com/catchorg/Catch2/releases/tag/v3.5.2

有人用吗?

热门库最近更新了什么

这个环节我会偶尔更新一下某些库最近的动态更新/代码讲解之类的

之前说想要搞但一直偷懒,这里更新一期seastar,下期folly/brpc之类的,也希望大家给点建议

seastar一直是非常积极跟进标准演进的库,代码新特性用的多,也和周边库配合的很好

比如配置fmt支持compile time string

最近的改动,他们给内置的内存池加了PROFILE配置

另外,有几个优化其实很小,比如判断内部peer已经用不到了,只clear但还占用内存,可以主动清掉

代码语言:javascript复制
diff --git a/include/seastar/core/shared_future.hh b/include/seastar/core/shared_future.hh
index 0e1e31e6..4a2ea71f 100644
--- a/include/seastar/core/shared_future.hh
    b/include/seastar/core/shared_future.hh
@@ -168,6  168,9 @@ class shared_future {
                     _peers.pop_front();
                 }
             }
             // _peer is now empty, but let's also make sure it releases any
             // memory it might hold in reserve.
             _peers = {};
             _keepaliver.release();
         }
代码语言:javascript复制

另外就是修复bug 同一个端口,同时listen同时accept场景应该抛异常

0 人点赞