strlen是否针对String Literals进行了优化?

时间:2018-05-08 16:00:00

标签: c++ c-strings string-length string-literals compile-time-constant

所以说我有这个:

const auto foo = "lorem ipsum"

如果我在代码中使用strlen(foo),是在运行时找到11还是在编译时注入?

3 个答案:

答案 0 :(得分:3)

答案取决于编译器和当前的优化级别。

使用此C ++代码快速进行实验

#include <cstring>
int strlen_of_const() {
    return strlen("lorem ipsum");
}
compiler explorer上的

显示,一些编译器会优化调用,而其他编译器会在运行时调用。例如,gcc优化了调用:

strlen_of_const():
  mov eax, 11
  ret
另一方面,MSVC保持通话:

$SG3533 DB        'lorem ipsum', 00H
EXTRN   strlen:PROC
strlen_of_const PROC
        sub      rsp, 40              ; 00000028H
        lea      rcx, OFFSET FLAT:$SG3533
        call     strlen
        add      rsp, 40              ; 00000028H
        ret      0
strlen_of_const ENDP

答案 1 :(得分:2)

这完全取决于您的编译器以及您是否在启用优化的情况下构建。

一个优秀的现代编译器可能会优化strlen并在优化时产生11作为常量,但语言中没有任何内容强制它。因此,编译器生成函数调用也是完全有效的。

您只需在所选的优化级别上使用您选择的编译器进行测试,然后阅读生成的程序集。

答案 2 :(得分:1)

该标准不允许实现添加constexpr,除非明确要求:

  

[constexpr.functions]
  本文档明确要求某些标准库函数是constexpr([dcl.constexpr])。   实现不应将任何标准库函数签名声明为constexpr,除非明确要求它。

所以strlen超出范围。

但是,为了支持constexpr的{​​{1}}构造函数,C ++ 17标准要求string_view的某些成员(如char_traits::length)仍然是constexpr。

本月我们有了gcc 8.1MSVC 15.7的新编译器版本,因此主要编译器的最新版本现在都将char_traits实现为constexpr。