为什么std :: cout将volatile指针转换为bool?

Jos*_*vin 16 c++ pointers iostream standards-compliance volatile

如果你试图cout指向volatile类型的指针,即使是你通常希望cout打印字符串的volatile指针,你只需要得到'1'(假设指针不是null我认为).我假设输出流operator <<是专门用于volatile指针的模板,但我的问题是,为什么?什么用例激发了这种行为?

示例代码:

#include <iostream>
#include <cstring>

int main()
{
    char x[500];
    std::strcpy(x, "Hello world");

    int y;
    int *z = &y;

    std::cout << x << std::endl;
    std::cout << (char volatile*)x << std::endl;

    std::cout << z << std::endl;
    std::cout << (int volatile*)z << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Hello world
1
0x8046b6c
1
Run Code Online (Sandbox Code Playgroud)

int*_*jay 28

ostream::operator<< 有以下重载,其中包括:

ostream& operator<< (bool val );
ostream& operator<< (const void* val );
Run Code Online (Sandbox Code Playgroud)

传入易失性指针时,第二个重载无法应用,因为如果没有显式强制转换,则无法将易失性指针转换为非易失性.但是,任何指针都可以转换为bool,因此选择第一个重载,您看到的结果是1或0.

因此,真正的原因不是代表标准委员会的故意决定,而只是标准没有指定带有易失性指针的重载.


小智 5

我认为原因是volatile指针不能隐式转换为void*.这在标准的附录C中,理由是类型安全.

更改:只有指向非常量和非易失性对象的指针可以隐式转换为void*基本原理:这样可以提高类型安全性.

因此,不是转换为void*(将以十六进制打印),而是将"默认"转换为bool.