为什么ostream为定义为volatile char []的字符串打印'1'?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (54)

考虑这个例子:

#include <cstdio>
#include <iostream>

int main() {
  volatile char test[] = "abc";
  std::printf("%s\n", test);
  std::cout << test << "\n";
}

用GCC编译并运行,得到如下输出:

$ g++ test.cc 
$ ./a.out 
abc
1
提问于
用户回答回答于

唯一合适的重载operator<<bool,因此数组被转换(通过指针)booltrue因为它的地址是非空的。1除非您使用std::boolalpha操纵器,否则这会输出。

它不能使用const char *会输出字符串的重载,或者const void *输出指针值的重载,因为这些转换需要移除volatile限定符。隐式指针转换可以添加限定符,但不能删除它们。

要输出字符串,你必须抛弃限定符:

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

但要注意,这会给出未定义的行为,因为数组将被访问,就好像它不是易失性的。

printf是一个古老的可变参数函数,没有类型安全性。该%s说明符使得它解释说法是const char *,不管它实际上是。

用户回答回答于

如果“cv2 T”比“cv1 T”更合适,则可将“指向cv1 T的指针”类型的值转换为类型“指向cv2 T的指针”的prvalue。

它使用的bool版本,因为它不是一个nullptr

如果从中删除易失性限定符test将提供期望的结果。我们可以通过参阅7.1.6.1 cv-qualifiers的6段看到:

如果试图通过使用具有非挥发性限定类型的glvalue引用一个用volatile限定类型定义的对象,则程序行为是未定义的。

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

所属标签

可能回答问题的人

  • 爸爸

    腾讯 · 客户端安全 (已认证)

    4 粉丝4 提问5 回答
  • 找虫虫

    0 粉丝0 提问5 回答
  • 不吃貓的鱼oo

    5 粉丝466 提问4 回答
  • uncle_light

    5 粉丝518 提问4 回答

扫码关注云+社区

领取腾讯云代金券