C++ 中文周刊 第128期

2024-07-30 14:22:05 浏览数 (2)

周刊项目地址 https://github.com/wanghenshui/cppweeklynews

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

126期代码抄错,这里指正一下

代码语言:javascript复制
consteval auto as_constant(auto value) {
    return value;
}
constexpr int Calc(int x) {  return 4 * x; }
// consteval int Calc(int x) {  return 4 * x; }
int main() {
    auto res = Calc(2); 
    // auto res = as_constant(Calc(2)); 
      res;  
    res = Calc(res); //编译不过
    return res;
}

之前抄成consteval了,这里感谢 @fanenr 指正

另外感谢 不语 汪总 赞助

资讯

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

八月提案 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/#mailing2023-08

编译器信息最新动态推荐关注hellogcc公众号 上周更新 2023-08-16 第215期 [1]

本周没更新

cppcon 2023开始卖票

文章

Common patterns of typos in programming[2]

代码review

memset用错,看不出问题的罚深蹲五个

代码语言:javascript复制
int64_t FileList::VMProcess(int OpCode,
                            void *vParam,
                            int64_t iParam)
{
  ....
  PluginInfo *PInfo = (PluginInfo *)vParam;
  memset(PInfo, 0, sizeof(PInfo));
  ....
}

里面还有各种越界/复制粘贴错误。懒得贴了

The unexpected cost of shared pointers[3]

一段简单的代码

代码语言:javascript复制
static constexpr std::size_t kLineSize = (1 << 23); // 8MB
 
struct Line {
  char _data[kLineSize];
  std::mutex _mtx;
  std::atomic<std::size_t> _size = 0;
};

    
auto line = std::make_shared<Line>();

查perf图有莫名其妙的memset

哈哈。之前咱们也提到过,数组,调用make_xx会帮你初始化,所以有memset

除了标准库给的make_unique_for_overwrite这种玩意之外,也可以定制构造函数,构造函数为空,啥也不做就行了

这个文章的标题不对了,这个其实和shared_ptr没啥关系,unique_ptr也有,本质是调用构造函数的问题,默认构造函数的问题

ow to Use Monadic Operations for std::optional in C 23 [4]
代码语言:javascript复制
std::optional<UserProfile> fetchFromCache(int userId);
std::optional<UserProfile> fetchFromServer(int userId);
std::optional<int> extractAge(const UserProfile& profile);

int main() {
    const int userId = 12345;

    const auto ageNext = fetchFromCache(userId)
        .or_else([&]() { return fetchFromServer(userId); })
        .and_then(extractAge)
        .transform([](int age) { return age   1; });

    if (ageNext)
        cout << format("Next year, the user will be {} years old", *ageNext);
    else 
        cout << "Failed to determine user's age.n";
}

就是介绍这几个新api的用法

其实看一下代码就懂了

C/C performance pitfall: int8_t, aliasing and the ways out[5]

还是老生常谈的 char*歧义,导致不能充分优化,要么就restrict,要么就换成 别的类型来操作

别的类型,可以是你自己封装一下char,也可以是char8_t,_BitInt(8) 别用vector std::byte, 没用,背后还是char,

以下两篇文章来自CppMore,大家也可以关注cppMore公众号

Compile time dispatching in C 20[6]

用fixed_stding做类型tag,tag有必要这么花哨吗

Monads in Modern C , What, Why, and How[7]

手把手教你熟悉monad,熟悉optional/expect/range,读者反馈讲的特好

其实就是状态链式流转,不知道为啥链式调用看起来很叼

现代C 学习——更好的单例模式[8]

直接看代码吧,其实c 11的东西

代码语言:javascript复制
template <typename T>
struct Singleton {
    Singleton() = default;
    ~Singleton() = default;

    // Delete the copy and move constructors
    Singleton(const Singleton &) = delete;
    Singleton &operator=(const Singleton &) = delete;
    Singleton(Singleton &&) = delete;
    Singleton &operator=(Singleton &&) = delete;

    static T &get() {
        static T instance{};
        return instance;
    }
};
Compile time string literal concatenation (or how to make your compiler cry)[9]

fixed_string怎么连接????

硬拷呗

代码语言:javascript复制
template <typename char_type, std::size_t N, std::size_t M>
constexpr auto concat_fixed_string(basic_fixed_string<char_type, N> l,
                                   basic_fixed_string<char_type, M> r) noexcept {
  basic_fixed_string<char_type, N   M> result;
  auto it{ std::copy(l.begin(), l.end(), result.begin()) };
  it = std::copy(r.begin(), r.end(), it);
  *it = {};
  return result;
}

代码来自 https://github.com/arturbac/small_vectors/blob/master/include/coll/basic_fixed_string.h

或者体验这个 c 20的版本 https://godbolt.org/z/Gdfnsf8Pa 也是硬来

C 异常与 longjmp[10]

看个乐

Phantom and indulgent shared pointers[11]

介绍shared_ptr各种转换之后的内存问题,控制块和实际内存块占用关系/判定

我的评价是就当不知道这个事儿吧,看了迷糊

On writing loops in PPL and continuation-passing style, part 1[12]
On writing loops in PPL and continuation-passing style, part 2[13]
On writing loops in PPL and continuation-passing style, part 3[14]

看得我眼睛疼

User-defined class qualifiers in C 23 [15]

利用boost::mp11来做tag

代码语言:javascript复制
#include <boost/mp11/algorithm.hpp>
#include <boost/mp11/list.hpp>
#include <type_traits>

template<typename T,typename... Qualifiers>
struct access: T
{
  using qualifier_list=boost::mp11::mp_list<Qualifiers...>;

  using T::T;
};

template<typename T, typename... Qualifiers>
concept qualified =
  (boost::mp11::mp_contains<
    typename std::remove_cvref_t<T>::qualifier_list,
    Qualifiers>::value && ...);

// some qualifiers
struct mut;
struct synchronized;

template<typename T>
concept is_mut =  qualified<T, mut>;

template<typename T>
concept is_synchronized = qualified<T, synchronized>;

struct X
{
  void foo() {}

  template<is_mut Self>
  void bar(this Self&&) {} 

  template<is_synchronized Self>
  void baz(this Self&&) {}

  template<typename Self>
  void qux(this Self&&)
  requires qualified<Self, mut, synchronized>
  {}
};

int main()
{
  access<X, mut> x;

  x.foo();
  x.bar();
  x.baz(); // error: associated constraints are not satisfied
  x.qux(); // error: associated constraints are not satisfied

  X y;
  x.foo();
  y.bar(); // error: associated constraints are not satisfied

  access<X, mut, synchronized> z;
  z.bar();
  z.baz();
  z.qux();
}

我觉得tag挺简单的,怎么看大家都实现的这么复杂

Transcoding Latin 1 strings to UTF-8 strings at 18 GB/s using AVX-512[16]

SIMD时间

常规

代码语言:javascript复制
 unsigned char byte = data[pos];
if ((byte & 0x80) == 0) { // if ASCII
  // will generate one UTF-8 byte
  *utf8_output   = (char)(byte);
  pos  ;
} else {
  // will generate two UTF-8 bytes
  *utf8_output   = (char)((byte >> 6) | 0b11000000);
  *utf8_output   = (char)((byte & 0b111111) | 0b10000000);
  pos  ;
}

SIMD

代码语言:javascript复制
__mmask32 nonascii = _mm256_movepi8_mask(input);
__mmask64 sixth =
_mm512_cmpge_epu8_mask(input, _mm512_set1_epi8(-64));
const uint64_t alternate_bits = UINT64_C(0x5555555555555555);
uint64_t ascii = ~nonascii;
uint64_t maskA = ~_pdep_u64(ascii, alternate_bits);
uint64_t maskB = ~_pdep_u64(ascii>>32, alternate_bits);
// interleave bytes from top and bottom halves (abcd...ABCD -> aAbBcCdD)
__m512i input_interleaved = _mm512_permutexvar_epi8(_mm512_set_epi32(
0x3f1f3e1e, 0x3d1d3c1c, 0x3b1b3a1a, 0x39193818,
0x37173616, 0x35153414, 0x33133212, 0x31113010,
0x2f0f2e0e, 0x2d0d2c0c, 0x2b0b2a0a, 0x29092808,
0x27072606, 0x25052404, 0x23032202, 0x21012000
), input);
// double size of each byte, and insert the leading byte
__m512i outputA = _mm512_shldi_epi16(input_interleaved, _mm512_set1_epi8(-62), 8);
outputA = _mm512_mask_add_epi16(outputA, (__mmask32)sixth, outputA, _mm512_set1_epi16(1 - 0x4000));
__m512i leadingB = _mm512_mask_blend_epi16((__mmask32)(sixth>>32), _mm512_set1_epi16(0x00c2), _mm512_set1_epi16(0x40c3));
__m512i outputB = _mm512_ternarylogic_epi32(input_interleaved, leadingB, _mm512_set1_epi16((short)0xff00), (240 & 170) ^ 204); // (input_interleaved & 0xff00) ^ leadingB
// prune redundant bytes
outputA = _mm512_maskz_compress_epi8(maskA, outputA);
outputB = _mm512_maskz_compress_epi8(maskB, outputB);

眼睛花了

代码在这里 https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/tree/master/2023/08/18

视频

  • • What is Low Latency C ? (Part 1) - Timur Doumler - CppNow 2023[17]
  • • What is Low Latency C ? (Part 2) - Timur Doumler - CppNow 2023[18]

太长了没看完。周末总结一下

开源项目需要人手

  • • asteria[19] 一个脚本语言,可嵌入,长期找人,希望胖友们帮帮忙,也可以加群384042845和作者对线
  • • Unilang[20] deepin的一个通用编程语言,点子有点意思,也缺人,感兴趣的可以github讨论区或者deepin论坛看一看。这里也挂着长期推荐了
  • • gcc-mcf[21] 懂的都懂

新项目介绍/版本更新

  • • https://github.com/fmtlib/fmt/releases/tag/10.1.0 fmt 速度更快了。推荐升级

本文永久链接[22]

如果有疑问评论最好在上面链接到评论区里评论,这样方便搜索,微信公众号有点封闭/知乎吞评论

引用链接

[1] 编译器信息最新动态推荐关注hellogcc公众号 上周更新 2023-08-16 第215期 : https://github.com/hellogcc/osdt-weekly/blob/master/weekly-2023/2023-01-04.md [2] Common patterns of typos in programming: https://pvs-studio.com/en/blog/posts/cpp/1064/ [3] The unexpected cost of shared pointers: https://oxla.com/the-unexpected-cost-of-shared-pointers/ [4] ow to Use Monadic Operations for std::optional in C 23 : https://www.cppstories.com/2023/monadic-optional-ops-cpp23/ [5] C/C performance pitfall: int8_t, aliasing and the ways out: https://gist.github.com/alexei-zaripov/dcc14c78819c5f1354afe8b70932007c [6] Compile time dispatching in C 20: https://www.cppmore.com/2023/08/16/compile-time-dispatching-in-cpp20/ [7] Monads in Modern C , What, Why, and How: https://www.cppmore.com/2023/08/14/monads-in-modern-c-what-why-and-how/ [8] 现代C 学习——更好的单例模式: https://zhuanlan.zhihu.com/p/651173499 [9] Compile time string literal concatenation (or how to make your compiler cry): https://www.reddit.com/r/cpp/comments/15z14hh/compile_time_string_literal_concatenation_or_how/ [10] C 异常与 longjmp: https://blog.hidva.com/2023/05/29/cppexception4/ [11] Phantom and indulgent shared pointers: https://devblogs.microsoft.com/oldnewthing/20230818-00/?p=108619 [12] On writing loops in PPL and continuation-passing style, part 1: https://devblogs.microsoft.com/oldnewthing/20230822-00/?p=108634 [13] On writing loops in PPL and continuation-passing style, part 2: https://devblogs.microsoft.com/oldnewthing/20230823-00/?p=108640 [14] On writing loops in PPL and continuation-passing style, part 3: https://devblogs.microsoft.com/oldnewthing/20230824-00/?p=108647 [15] User-defined class qualifiers in C 23 : http://bannalia.blogspot.com/2023/08/user-defined-class-qualifiers-in-c23.html [16] Transcoding Latin 1 strings to UTF-8 strings at 18 GB/s using AVX-512: https://lemire.me/blog/2023/08/18/transcoding-latin-1-strings-to-utf-8-strings-at-12-gb-s-using-avx-512/ [17] What is Low Latency C ? (Part 1) - Timur Doumler - CppNow 2023: https://www.youtube.com/watch?v=EzmNeAhWqVs&ab_channel=CppNow [18] What is Low Latency C ? (Part 2) - Timur Doumler - CppNow 2023: https://www.youtube.com/watch?v=5uIsadq-nyk&ab_channel=CppNow [19] asteria: https://github.com/lhmouse/asteria [20] Unilang: https://github.com/linuxdeepin/unilang [21] gcc-mcf: https://gcc-mcf.lhmouse.com/ [22] 本文永久链接: https://wanghenshui.github.io/cppweeklynews/posts/128.html

0 人点赞