C++ 中文周刊 2024-07-27 第165期

周刊项目地址

公众号

点击「查看原文」跳转到 GitHub 上对应文件,链接就可以点击了

qq群 点击进入

RSS

欢迎投稿,推荐或自荐文章/软件/资源等,评论区留言

本期文章由 Amniesia HNY Damon 赞助

最近的热门是windows蓝屏事件了,其实国内外安全都有关系户

本期内容不多


资讯

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

编译器信息最新动态推荐关注hellogcc公众号 本周更新 264期

文章

Safer code in C++ with lifetime bounds

llvm和msvc支持生命周期检查,返回string_view有概率悬空,用错

std::string_view my_get_host(std::string_view url_string) {
  auto url = ada::parse(url_string).value();
  return url.get_host();
}

比如这种用法明显就是错的,加上编译检查能抓出来

#ifndef __has_cpp_attribute
    #define ada_lifetime_bound
#elif __has_cpp_attribute(msvc::lifetimebound)
    #define ada_lifetime_bound [[msvc::lifetimebound]]
#elif __has_cpp_attribute(clang::lifetimebound)
    #define ada_lifetime_bound [[clang::lifetimebound]]
#elif __has_cpp_attribute(lifetimebound)
    #define ada_lifetime_bound [[lifetimebound]]
#else
    #define ada_lifetime_bound
#endif

...

std::string_view get_host() const noexcept ada_lifetime_bound;

编译报错

fun.cpp:8:10: warning: address of stack memory associated with local variable 'url' returned [-Wreturn-stack-address]
    8 |   return url.get_host();

想要了解可以看这里 https://clang.llvm.org/docs/AttributeReference.html#lifetimebound

strlcpy and how CPUs can defy common sense strlcpy and how CPUs can defy common sense

strlcpy 实现openbsd和glibc实现不同,openbsd是这样的

size_t strlcpy(char *dst, const char *src, size_t dsize)
{
    const char *osrc = src;
    size_t nleft = dsize;

    if (nleft != 0) while (--nleft != 0) { /* Copy as many bytes as will fit. */
        if ((*dst++ = *src++) == '\0')
            break;
    }

    if (nleft == 0) { /* Not enough room in dst, add NUL and traverse rest of src. */
        if (dsize != 0) *dst = '\0'; /* NUL-terminate dst */
        while (*src++) ;
    }

    return(src - osrc - 1);	/* count does not include NUL */
}

能看到是一边复制一边移动的,没有提前算出src边界,而glibc是用strlen先计算src长度的,相当于重复计算了

所以openbsd版本应该比glibc版本快是不是?并不

考虑到strlen和memcpy有可能优化,咱们手写一个版本

size_t bespoke_strlcpy(char *dst, const char *src, size_t size)
{
    size_t len = 0;
    for (; src[len] != '\0'; ++len) {} // strlen() loop

    if (size > 0) {
        size_t to_copy = len < size ? len : size - 1;
        for (size_t i = 0; i < to_copy; ++i) // memcpy() loop
            dst[i] = src[i];
        dst[to_copy] = '\0';
    }
    return len;
}

编译使用 -fno-builtin避免strlen memcpy优化

这个也比openbsd快

实际上没有长度信息 每次都要判断\0,严重影响优化,循环出现依赖,没法彻底优化

What’s so hard about constexpr allocation?

讨论constexpr vector难做的原因,先从unique_ptr开始讨论,constexpr导致相关的传递语义发生变化,不好优化

考虑引入新关键字propconst 标记常量传递 讨论的还是比较有深度的,感兴趣的可以读一下

Does C++ allow template specialization by concepts?

用require实现函数偏特化

template <typename T>
void clear(T & t);


template <typename T>
concept not_string =
!std::is_same_v<T, std::string>;


template <>
void clear(std::string & t) {
  t.clear();
}


template <class T>
void clear(T& container) requires not_string<T> {
  for(auto& i : container) {
    i = typename T::value_type{};
  }
}

看一乐

Scan HTML even faster with SIMD instructions (C++ and C#)

实现特殊版本find_first_of 向量化。代码不贴了,感兴趣的看一下

开源项目介绍

互动环节

看了死侍金刚狼 还可以。现在漫威太垃圾了,这还算能看的

实际剧情和银河护卫队差不多,不能细想反派,看个乐呵


上一期

看到这里或许你有建议或者疑问或者指出错误,请留言评论! 多谢! 你的评论非常重要!也可以帮忙点赞收藏转发!多谢支持! 觉得写的不错那就给点吧, 在线乞讨 微信转账