在 The C ++ Programming Language 一书的第9.2节中,Bjarne Stroustrup写道:
请注意,默认情况下会初始化在全局或命名空间范围内未定义初始值设定项的变量。对于在免费商店中创建的局部变量或对象,情况并非如此。
但是以下程序打印的值为0:
#include <iostream>
using namespace std;
int main() {
int x;
cout << x << endl;
return 0;
}
它不应该返回某种错误吗?
我使用g++
进行编译。
答案 0 :(得分:6)
但是以下程序在我的终端上输出值为0。
它有未定义的行为,因为cout
行试图从未初始化的int
读取。您看到的任何输出,实际上任何行为都无法保证。
它不应该返回某种错误吗?
不,这不是未定义行为的工作原理。您可能会或可能不会看到错误。
答案 1 :(得分:5)
x
未初始化,因此您的代码段实际上有undefined behavior。
它不应该返回某种错误吗?
g++
默认情况下不会对未初始化的值发出警告。
如果您希望编译器显示警告,则需要-Wuninitialized
选项:
g++ -Wuninitialized your_file.c
您应该使用-Wall
选项来启用此警告以及许多其他有用的警告。
有关警告选项here
的更多信息答案 2 :(得分:2)
它不应该返回某种错误吗?
不,它不应该,但Valgrind可以检测到此错误:
$ valgrind --track-origins=yes ./a.out
==4950== Memcheck, a memory error detector
==4950== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4950== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==4950== Command: ./a.out
==4950==
==4950== Conditional jump or move depends on uninitialised value(s)
==4950== at 0x4F4444A: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:874)
==4950== by 0x4F504C4: put (locale_facets.h:2371)
==4950== by 0x4F504C4: std::ostream& std::ostream::_M_insert<long>(long) (ostream.tcc:73)
==4950== by 0x40076D: main (t.cpp:5)
==4950== Uninitialised value was created by a stack allocation
==4950== at 0x400757: main (t.cpp:3)
==4950==
Valgrind产出的这一部分明确指出:
==4950== Uninitialised value was created by a stack allocation
==4950== at 0x400757: main (t.cpp:3)
==4950==