所以说我有这个:
const auto foo = "lorem ipsum"
如果我在代码中使用strlen(foo)
,是在运行时找到11还是在编译时注入?
答案 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.1和MSVC 15.7的新编译器版本,因此主要编译器的最新版本现在都将char_traits
实现为constexpr。