为什么ostream为定义为"volatile char []"的字符串打印"1"? [英] Why does ostream prints `1` for a string defined as `volatile char[]`?

查看:71
本文介绍了为什么ostream为定义为"volatile char []"的字符串打印"1"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下(人工)示例:

Consider this (artificial) example:

#include <cstdio>
#include <iostream>

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

使用GCC对其进行编译并运行,将产生以下输出:

Compiling it with GCC and running gives the following output:

$ g++ test.cc 
$ ./a.out 
abc
1

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

As you can see printf prints the string correctly while cout prints 1. Why does writing to cout produces 1 in this case?

推荐答案

operator<<的唯一合适的重载是bool的重载,因此将数组(通过指针)转换为bool,得到,因为其地址为非null.除非使用std::boolalpha操纵器,否则输出为1.

The only suitable overload of operator<< is that for bool, so the array is converted (via a pointer) to bool, giving true since its address is non-null. This outputs as 1 unless you use the std::boolalpha manipulator.

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

It can't use the overload for const char * which would output the string, or that for const void * which would output the pointer value, since those conversions would require removing the volatile qualifier. Implicit pointer conversions can add qualifiers, but can't remove them.

要输出字符串,您必须舍弃限定符:

To output the string, you'd have to cast away the qualifier:

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

但是要注意,这会带来不确定的行为,因为将访问数组时就好像它不是易失的.

but beware that this gives undefined behaviour since the array will be accessed as if it were not volatile.

printf是老式的可变参数函数,不提供类型安全性. %s说明符使它可以将参数解释为const char *,无论它实际上是什么.

printf is an old-school variadic function, giving no type safety. The %s specifier makes it interpret the argument as const char *, whatever it actually is.

这篇关于为什么ostream为定义为"volatile char []"的字符串打印"1"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆