问题是,以下代码片段使用未初始化的内存吗?这是由Google的MemorySanitizer报告的吗?还是一个误报?:
main.cpp
:
#include <string>
#include <iostream>
using namespace std;
int main() {
string s0 = to_string(1);
cout << "s0: " << s0 << endl;
string s1 = to_string(1) + to_string(2);
cout << "s1: " << s1 << endl;
return 0;
}
Makefile
:
main:
clang++ -fsanitize=memory -fsanitize-memory-track-origins -fPIE -pie -fno-omit-frame-pointer -g -O2 main.cpp -o main-msan.out
clang++ -O2 main.cpp -o main.out
结果:
./main-msan.out
s0: 1
==122092==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x55a7354e5cf7 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:6123:34
#1 0x55a7354e5cf7 in main <my_directory>/msan/main.cpp:9:30
#2 0x7f201f6edd09 in __libc_start_main csu/../csu/libc-start.c:308:16
#3 0x55a735468349 in _start (<my_directory>/msan/main-msan.out+0x21349)
Uninitialized value was created by an allocation of 'ref.tmp' in the stack frame of function 'main'
#0 0x55a7354e4d90 in main <my_directory>/msan/main.cpp:6
SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:6123:34 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&)
Exiting
这里也开放了一个镜像问题 (点击此处)
string s1 = to_string(111) + to_string(222);
,但还是会触发警告。而且为了使用MemorySanitizer,我必须使用clang++
。 - D.J. Elkinduint32_t a, b; uint32_t c = a + b;
将使c
成为“未指定值”,如第3.19.3节所定义。但标准在哪里说这会触发UB呢? - D.J. Elkind