使用带有 std::cout 的 volatile c-string [重复]

Posted

技术标签:

【中文标题】使用带有 std::cout 的 volatile c-string [重复]【英文标题】:Using volatile c-string with std::cout [duplicate] 【发布时间】:2018-09-15 10:53:10 【问题描述】:

我有以下代码

#include <iostream>
#include <cstdio>
volatile char s[7] = "test";
int main() 
   std::cout << s << std::endl;
   std::printf("%s\n", s);

它用 std::cout 打印“1”,用 std::printf 打印“test”。为什么它在第一种情况下打印“1”?!我的系统是“Linux debian 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2+deb9u5 (2017-09-19) x86_64 GNU/Linux”,我的 C++ 编译器是“g++ (GCC) 7.3.0” .

如果我删除“volatile”关键字,则 std::cout 会打印预期的“test”。

【问题讨论】:

我怀疑使用 volatile char*%s 是未定义的行为。 【参考方案1】:

printf 是可变参数,因此可以接受任何类型的参数。 cout 是更强类型的 C++ 事物。 char const volatile* 不会隐式转换为 char const*。但它转换为bool。因此 1.

【讨论】:

这算是标准库的bug吗? 我不会称之为错误。但这肯定是出乎意料的行为。就像在 Windows 中尝试通过 cout 输出宽字符串或通过 wcout 输出窄非 ASCII 字符串一样。 我认为标准库对于char *void *的易失版本应该有重载 我不完全确定,在打印时其字符(也意味着它的长度)可以改变的字符串的预期输出是什么?更一般地说,几乎每个库中的常见模式是忽略 volatile 指针;如果指向的对象“足够稳定”可以对其进行处理,则调用者可以通过丢弃volatile 来确认它。

以上是关于使用带有 std::cout 的 volatile c-string [重复]的主要内容,如果未能解决你的问题,请参考以下文章

带有 std::cout 的多线程控制台文本动画

挂在 std::cout 上的 GDB 调试器

带有 char、double、int 和 t 的结构的大小 [重复]

使用 std::addressof(std::cout) 代替 &std::cout 有啥风险吗?

带有 cout 的编译器错误消息

为啥 std::bitset 不带有迭代器?