#include <iostream>
#include <string>
using namespace std;
template<class T> class Sample {
private:
T val;
public:
Sample(T InitialVal=T()) : val(InitialVal)
{
// do nothing
}
~Sample()
{
// do nothing
}
void PrintVal(void)
{
try {
cout << "[" << val << "]" << endl;
} catch(...) {
cout << "exception thrown" << endl;
}
}
};
int main() {
// your code goes here
Sample<int> ints(20), intd;
Sample<char *> chars(const_cast<char*>("Neelakantan")), charsd;
Sample<string> s, ss("neel");
ints.PrintVal();
intd.PrintVal();
chars.PrintVal();
charsd.PrintVal(); // <<- Culprit line. Commenting out this line works as expected.
s.PrintVal();
ss.PrintVal();
return 0;
}
当我运行上面的代码时,我得到以下输出:
sh-4.4$ g++ -o main *.cpp
sh-4.4$ main
[20]
[0]
[Neelakantan]
[sh-4.4$
当我注释掉“
charsd.PrintVal();
”行时,得到以下输出:[sh-4.4$ g++ -o main *.cpp
sh-4.4$ main
[20]
[0]
[Neelakantan]
[]
[neel]
sh-4.4$
Sample 类型的模板实例的'charsd'对象有什么问题?没有异常被抛出。
编译器版本:
sh-4.4$ g++ --version
g++ (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
sh-4.4$
最佳答案
[根据新的信息/知识修改后的答案。另请参阅乔纳森·韦克利(Jonathan Wakeley)的答案(我在看到之前对此进行了更新),他是gcc / libstdc ++的撰稿人,并且选择了我提交的错误报告。非常感谢他为我做出直率而真诚的道歉,因为我做出了荒谬的假设,即ostream
始终会像我之前描述的那样表现。
实际上,在故障点,您实际上正在做的是:
std::cout << (const char *) nullptr << std::endl;
大多数人期望得到的结果(尽管严格来说,您在这里所做的行为是不确定的)将是SEGFAULT。
但是,其中包含
libstdc++,
使用的ostream
的实现的gcc
有所不同。它在流上设置badbit
,并且仅当您启用了badbit
异常(默认情况下处于禁用状态)时,它(也会)引发异常。感谢Jonathan Wakeley在我提交有关此问题的错误报告时向我指出这一点,当我发布此答案的第一个版本时,我对此一无所知(显然也没有其他人向此主题发布)。但是您的代码没有启用所述异常,因此所有发生的事情是
badbit
被设置为cout
,并且随后所有后续写入均以静默方式失败。以前,我误解了这一点,因为传入nullptr时程序正在悄悄退出,但是我错了,并且我向开发人员表示歉意,因为他们做出了这种不必要的假设。评论中有更多关于此的内容。因此,要在发生这种情况时引发异常,必须在流上启用
badbit
异常,您可以这样操作:std::cout.exceptions (std::ostream::badbit | std::ios::failbit);
然后,您将获得希望的异常。就我个人而言,我不太喜欢这种行为,我更喜欢SEGFAULT(实际上,使用clang you do),但Jonathan告诉我,自2002年以来就是这样,开发人员有充分的理由不这样做立即更改。
有一个新的live demo显示了
gcc
的行为,并添加了以上一行,现在的输出为:[20]
[0]
[Neelakantan]
terminate called after throwing an instance of 'std::__ios_failure'
what(): basic_ios::clear: iostream error
[
Aborted
因此,请注意,陷入混乱的陷阱在于在那里等待,“为什么我的日志记录语句没有突然出现?”或类似的东西。