Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么ostream会为定义为“volatile char[]”的字符串打印“1”?_C++_String_Printf_Iostream_Volatile - Fatal编程技术网

C++ 为什么ostream会为定义为“volatile char[]”的字符串打印“1”?

C++ 为什么ostream会为定义为“volatile char[]”的字符串打印“1”?,c++,string,printf,iostream,volatile,C++,String,Printf,Iostream,Volatile,考虑这个(人为的)例子: 如您所见,printf正确打印字符串,而cout打印1。在这种情况下,为什么写入cout会产生1 “指针指向cv1 T”类型的PR值可转换为PR值 如果“cv2 T”比“cv1 T”更符合cv条件,则键入“指向cv2 T的指针” 因此它使用的是bool版本,由于它不是nullptr,因此结果是true 如果从test中删除volatile限定符,这将提供您期望的结果。一些答案建议使用const\u cast删除volatile限定符,但这是未定义的行为。我们可以通过查看

考虑这个(人为的)例子:

如您所见,
printf
正确打印字符串,而
cout
打印
1
。在这种情况下,为什么写入
cout
会产生
1

“指针指向cv1 T”类型的PR值可转换为PR值 如果“cv2 T”比“cv1 T”更符合cv条件,则键入“指向cv2 T的指针”

因此它使用的是
bool
版本,由于它不是
nullptr
,因此结果是
true

如果从
test
中删除volatile限定符,这将提供您期望的结果。一些答案建议使用
const\u cast
删除volatile限定符,但这是未定义的行为。我们可以通过查看第7.1.6.1节来了解cv限定符第6段,其中说明:

如果试图引用由 通过使用带有 非易失性限定类型,程序行为未定义


const_cast
在这种情况下,会生成一个prvalue,但取消引用该指针会生成一个左值,该左值将调用未定义的行为。

通过最少的web搜索找到的
操作符答案的唯一合适重载:


简短回答:
cout
由于
volatile
限定符,正在将对象解释为
bool
。这是
重载的一个怪癖,是
volatile
限定符将其强制转换为
bool
,请尝试:

std::cout << const_cast<char*>(test) << "\n";

std::cout
volatile char[N]
匹配
bool
优于
const char*
。事实上,它根本不匹配
constchar*
。@sharth太棒了,我甚至没想过要找一个dup。他们很接近,可能会很好地合并。这在技术上合法吗?Can
operator使用类型转换的答案具有未定义的行为:C++14[dcl.type.cv]p6说“如果试图通过使用glvalue和非易失性限定类型引用使用易失性限定类型定义的对象,则程序行为未定义。”您通常只能通过元素上的手写循环与易失性数组进行交互。@JeffreyYasskin我想知道这一点,但在这种情况下,
const_cast
会产生一个
prvalue
,据我所知,但我还没有详细考虑。@ShafikYaghmour:
const_cast
会产生一个prvalue
const char*
指向volatile数组的第一个元素([expr.const.cast])。但这仅仅意味着指针是一个右值,而不是它指向的任何东西。取消对该指针的引用会产生一个引用第一个元素([expr.unary.op])的左值,该元素会给出未定义的行为。@RaymondChen:是的,你说得对,它会给出未定义的行为。我添加了一个警告。这个答案有未定义的行为:C++14[dcl.type.cv]p6说“如果试图通过使用非易失性限定类型的glvalue引用使用易失性限定类型定义的对象,则程序行为未定义。”@JeffreyYasskin猜测该变量相当<代码>易失性
!;)
$ g++ test.cc 
$ ./a.out 
abc
1
std::cout << const_cast<const char*>(test) << "\n";
std::cout<< (char*)test <<std::endl;
std::cout << const_cast<char*>(test) << "\n";