添加volatile关键字后C++程序输出异常的原因探究
为何添加volatile后指针输出变成1?
问题现象
先看正常运行的代码:
#include <memory> #include <string> #include <iostream> int main() { std::string s = "Hi\n"; std::cout << s; auto p = std::make_unique<const char *>(s.c_str()); std::cout << *(p.get()); return 0; }
输出符合预期:
Hi Hi
但给指针类型加上volatile后:
#include <memory> #include <string> #include <iostream> int main() { std::string s = "Hi\n"; std::cout << s; auto p = std::make_unique<volatile const char *>(s.c_str()); std::cout << *(p.get()); return 0; }
输出变成了:
Hi 1
即便用reinterpret_cast强制转换,结果还是一样。
原因解析
问题出在std::ostream的运算符重载匹配上:
- 当输出
const char*时,std::cout会调用专门的重载,把它当作C风格字符串输出内容。 - 但
volatile const char*是独立的类型,标准库并没有为这个类型提供对应的operator<<重载。此时编译器会寻找最匹配的重载规则,而任何指针类型都可以隐式转换为bool,于是就匹配到了输出布尔值的重载。 - 由于你的指针是非空的,布尔值为
true,std::cout默认会将true打印为1,这就是你看到的结果。
如果要输出字符串内容,需要显式转换回const char*(前提是你能确定此时volatile限定符不再必要,或能保证内存访问安全),示例代码:
std::cout << const_cast<const char*>(*(p.get()));
内容的提问来源于stack exchange,提问作者Roman Pavelka
相关产品推荐
相关产品推荐

