C++ 中文周刊 第43期

reddit/hackernews/lobsters摘抄一些c++动态

周刊项目地址在线地址知乎专栏 腾讯云+社区

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

本周有点忙,内容较少


资讯

编译器信息最新动态推荐关注hellogcc公众号 OSDT Weekly 2021-12-22 第129期

标准委员会邮件列表 12月

zstd 1.5.1 发布相比旧版有很大性能提升,和lz4很接近了

Intel oneAPI Toolkits 2022 Released 包括TBB在内的一系列更新

文章

之前也介绍过Jason Turner的这个书,实际上一直是开源的,之前也有人总结过,关注进展的可以点点star

最近不是出了一个新链接器linker mold比ld快么,作者研究一下为啥ld lld慢 (很多能做并行化的地方没做)

linker我不是很懂,可以读读

简单说就是optional T&比T*表达效果更好

静态代码检查公司,介绍了他们公司分析代码遇到的十个典型bug,这里列几个好笑的

void
gsk_vulkan_image_upload_regions (GskVulkanImage    *self,
                                 GskVulkanUploader *uploader,
                                 guint              num_regions,
                                 GskImageRegion    *regions)
{
  ....
  for (int i = 0; i < num_regions; i++)
  {
    m = mem + offset;
    if (regions[i].stride == regions[i].width * 4)
    {
      memcpy (m, regions[i].data, regions[i].stride * regions[i].height);
    }
    else
    {
      for (gsize r = 0; r < regions[i].height; i++)          // <=
        memcpy (m + r * regions[i].width * 4,
                regions[i].data + r * regions[i].stride, regions[i].width * 4);
    }
    ....
  }
  ....
}

坑爹的循环用错变量。。。

QString QPixelTool::aboutText() const
{
  const QList<QScreen *> screens = QGuiApplication::screens();
  const QScreen *windowScreen = windowHandle()->screen();

  QString result;
  QTextStream str(&result);
  str << "<html></head><body><h2>Qt Pixeltool</h2><p>Qt " << QT_VERSION_STR
    << "</p><p>Copyright (C) 2017 The Qt Company Ltd.</p><h3>Screens</h3><ul>";
  for (const QScreen *screen : screens)
    str << "<li>" << (screen == windowScreen ? "* " : "  ")
        << screen << "</li>";
  str << "<ul></body></html>";
  return result;
}

html字符串不匹配 最后应该是/ul

#define PM_EXP2(A) 1 << A

int process_val(const u_int8_t *data, u_int32_t data_len,
                               u_int32_t *retvalue, ....) 
{
  *retvalue = 0;
  ....
  /* Now find the actual value */
  for (; i < data_len; i++) {
    *retvalue += data[i] * PM_EXP2(8 * (data_len - i - 1));
  }
  return(0);
}

不安全的宏,A得括起来,不然求职顺序有问题

搞错被除数。这个代码就不列了

// bitsperlong.h
#ifdef CONFIG_64BIT
#define BITS_PER_LONG 64
#else
#define BITS_PER_LONG 32
#endif /* CONFIG_64BIT */

// bits.h
/*
 * Create a contiguous bitmask starting at bit position @l and ending at
 * position @h. For example
 * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
 */
#define __GENMASK(h, l) ....

// master.h
#define I2C_MAX_ADDR      GENMASK(6, 0)

// master.c
static enum i3c_addr_slot_status
i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr)
{
  int status, bitpos = addr * 2;                   // <=

  if (addr > I2C_MAX_ADDR)
    return I3C_ADDR_SLOT_RSVD;

  status = bus->addrslots[bitpos / BITS_PER_LONG];
  status >>= bitpos % BITS_PER_LONG;               // <=

  return status & I3C_ADDR_SLOT_STATUS_MASK;
}

代码的类型不匹配,溢出风险

extern void eFree (void *const ptr);

extern void argDelete (Arguments* const current)
{
  Assert (current != NULL);
  if (current->type ==  ARG_STRING  &&  current->item != NULL)
    eFree (current->item);
  memset (current, 0, sizeof (Arguments));  // <=
  eFree (current);                          // <=
}

// routines.c
extern void eFree (void *const ptr)
{
  Assert (ptr != NULL);
  free (ptr);
}

检测出多余的memset

std::size_t m_trail; 
....
inline int context::execute(const char* data, std::size_t len,
 std::size_t& off)
{
  ....
  case MSGPACK_CS_EXT_8: {
                uint8_t tmp;
                load<uint8_t>(tmp, n);
                m_trail = tmp + 1;
                if(m_trail == 0) {
                    unpack_ext(m_user, n, m_trail, obj);
                    int ret = push_proc(obj, off);
                    if (ret != 0) return ret;
                }
                else {
                    m_cs = MSGPACK_ACS_EXT_VALUE;
                    fixed_trail_again = true;
                }
            } break;
  ....
}

死代码

template<typename T>
static ALWAYS_INLINE void FormatLogMessageAndPrintW(....)
{
  ....
  wchar_t wbuf[512];
  wchar_t* wmessage_buf = wbuf;
  ....
  if (wmessage_buf != wbuf)
  {
    std::free(wbuf);
  }
  if (message_buf != buf)
  {
    std::free(message_buf);
  }
  ....
}

意外释放

如何用宏实现反射?boost describe库的原理是什么?

truct X
{
  int m1;
  int m2;
};

BOOST_DESCRIBE_STRUCT(X, (), (m1, m2))

代码仓库在这里 挺有意思

其实也见过很多人实现过,就是一些信息/类型通过fixed_string之类的模版藏起来。

视频

cppcon2021基本都放出来了,时间比较紧张,这里慢慢看慢慢总结了,大家有看完了的也可以给咱投稿,咱备注引用/来源

项目

可以先看个简单版本 理解一下这玩意的原理,再看这个。不过都是玩具,看个乐。想用可以用boost的 circular_buffer (也是支持动态扩容的)

工作招聘

这俩招聘暂时放一个月。主要是没新的

昆仑数据库,魔改mysql的,还支持远程工作,友情推荐一波

现在mysql的代码已经很现代c++了

开发深度学习编译器,而且他们也支持远程工作,c++的,友情推荐一波


本文永久链接

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