为何static_cast无法将ulong转为uchar*?C风格转换却可行
static_cast却无法转换unsigned long*到unsigned char*? 以下代码使用C风格强制转换可以正常编译运行:
BCRYPT_ALG_HANDLE hAlg = nullptr; DWORD HashObjectSize = 0; ULONG CopyByte = NULL; status = BCryptGetProperty ( hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&HashObjectSize, // unsigned long* 转换为 unsigned char* sizeof(PUCHAR), &CopyByte, NULL );
但将其中的C风格转换替换为static_cast<PUCHAR>(&HashObjectSize)时,会触发“Invalid conversion”错误。已知DWORD等价于unsigned long,PUCHAR等价于unsigned char*,需要解释两者的差异。
回答
C风格强制转换的特性:C风格转换是一种无差别转换,它会绕过C++的类型安全检查机制,不管两种指针类型是否存在关联,直接对底层地址值进行转换。对于
unsigned long*到unsigned char*这种完全无关的指针类型转换,C风格转换会直接把前者的地址值当作后者的指针使用,不做任何兼容性校验。static_cast的类型安全限制:static_cast是C++为类型安全设计的转换运算符,仅允许在存在兼容关系的类型之间转换:比如派生类指针转基类指针、数值类型互转、void*与其他指针类型互转等。而unsigned long*和unsigned char*指向的是完全独立的对象类型,不存在继承或兼容关系,因此static_cast会直接拒绝这种转换,避免潜在的类型错误。正确的C++转换方式:如果确实需要这类底层地址转换(比如调用
BCryptGetProperty这类需要字节级访问的API),应该使用reinterpret_cast<PUCHAR>(&HashObjectSize)。它专门用于处理无关联类型之间的指针/引用转换,既明确表达了“重新解释地址含义”的意图,又比C风格转换更符合C++的类型规范。
内容的提问来源于stack exchange,提问作者Arthur Akopiants

