C++ 中文周刊 第113期

周刊项目地址

公众号

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

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

提交 issue

感谢 不语 GYXL 赞助


资讯

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

编译器信息最新动态推荐关注hellogcc公众号 本周更新 2023-05-10 第201期

bRPC CVE-2023-31039 漏洞修复报告

尽快升级到 bRPC >= 1.5.0,或者应用这个PR https://github.com/apache/brpc/pull/2218

出问题的代码

- static std::string ExpandPath(const std::string &path) {
-   if (path.empty()) {
-       return std::string();
-   }
-   std::string ret;
-   wordexp_t p;
-   wordexp(path.c_str(), &p, 0);
-   CHECK_EQ(p.we_wordc, 1u);
-   if (p.we_wordc == 1) {
-       ret = p.we_wordv[0];
-   }
-   wordfree(&p);
-   return ret;
- }

 void Server::PutPidFileIfNeeded() {
-   _options.pid_file = ExpandPath(_options.pid_file);
    if (_options.pid_file.empty()) {
        return;
    }

pid_file可能恶意注入命令

文章

一套ASIO相关的设计分析,很长见识

通过模版把内部参数透出来,这个其实就是folly::resizeWithoutInitialization的技巧。之前咱们说过多次,通过模版参数猥琐的访问private

struct header { int type{}; };

int main() {
    std::cout << []<auto Ptr>(const auto& msg) {
        return msg.*Ptr;
    }.operator()<&header::type>(header{42});  // prints 42
}

folly代码在这里 https://github.com/facebook/folly/blob/main/folly/memory/UninitializedMemoryHacks.h

最简单的复现代码段

#include <iostream>

class A {
private:
  void f(int) { std::cout << "whoops" << std::endl; }
};

using PMember = void (A::*)(int);

void hijack(A& s, int n, char dummy = 0);

template <PMember pf, typename T>
struct Hijack {
  friend void hijack(A& s, int n, T) {
    (s.*pf)(n);
  }
};

template struct Hijack<&A::f, char>;

int main() {
  A a;
  hijack(a, 10);
  return 0;
}

来自 http://www.gotw.ca/gotw/076.htm

有点意思

确实没啥用,尽量别用

cuda中文资料少,感兴趣的可以看看

看代码

struct Animal {
    explicit Animal() = default;
    virtual std::unique_ptr<Animal> clone() const = 0;
    virtual std::string noise() const = 0;
    virtual ~Animal() = default;
};

struct Cat : public Animal {
    std::unique_ptr<Animal> clone() const override {
        return std::make_unique<Cat>(*this);
    }
    std::string noise() const override {
        return "meow";
    }
};

int main() {
    std::unique_ptr<Animal> a = std::make_unique<Cat>();
    auto b = a->clone();
    assert(b->noise() == "meow");
}

没啥问题,就是会有告警 : deprecated user-declared destructor

是clone调用赋值构造弄出来的。

怎么干掉这个烦人的告警?定义好这几个构造函数就行了

struct Animal {
    explicit Animal() = default;
    virtual std::unique_ptr<Animal> clone() const = 0;
    virtual std::string noise() const = 0;
    Animal(const Animal&) = default;
    Animal& operator=(const Animal&) = delete;
    virtual ~Animal() = default;
};

或者别用clone这种用法

@LH_Mouse指出,可以clone里塞一个指针来传出来,而不是返回。总之这个工厂模式返回,很老套

视频

开IPO/LTO帮你优化代码,同时也有告警提示,有助于修复bug,什么,你说你不会?

# Optional IPO. Do not use IPO if it's not supported by compiler.
check_ipo_supported(RESULT result OUTPUT output)
if(result)
  set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
  message(WARNING "IPO is not supported: ${output}")
endif()

这哥们是libtorrent bdencode维护者,讲了一下他的代码优化过程,他很久之前是写了个博客记录这个视频的,https://blog.libtorrent.org/2015/03/bdecode-parsers/

简单说就是一个parser,解析类似json的结构 比如{ "foobar": [42, "barfoo", "bufar"] }

正常的思路就是解析成map,然后里头解析成vector

这是最直观的做法,但是有个问题,就是分配占大头,很多开销,而且数据结构也复杂立体化了,map vector,都是异构的,维护起来老太太裹脚布一层又一层

不知道大家伙玩没玩过QT的下拉菜单控件,那个数据接口套的,左一层右一层,编辑一下要了老命了

有没有什么优化手段呢?拍扁,什么map vector,这种容器信息变成结构体的一部分

作者从 https://github.com/zserge/jsmn 这个json parser得到启发,直接拍扁处理,整一数组来表示,彻底没有各种容器造成的低效问题,性能直接翻好几倍

代码在这里 https://github.com/arvidn/bdecode

开源项目需要人手

新项目介绍/版本更新


本文永久链接

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

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