我遇到的是我的编译器拒绝将我的unsigned char指针强制转换为带符号的char指针。我困惑了一会儿,因为我一直在使用static_cast来转换最长时间的签名。
然后我做了一点挖掘(好吧,它不是很深。我做了一点舀!)尽管现在我明白了static_cast
防止指针式铸造正好是为什么它是更安全和更好的投射方式(比可能调用实现定义的行为或未定义的行为的传统替代方案),我仍然不确定我应该为我的情况做些什么。
我在这里是对OpenGL API函数的调用,其签名是
void glShaderSource(
GLuint shader, GLsizei count, const GLchar **string, const GLint *length
);
我最近更改了文件阅读器API,以便不再将文件读取的数据作为char *
返回,而是使用unsigned char *
执行此操作。这个更改没有出错,因为我觉得unsigned char对原始数据的处理能力要好得多(即使它可能是ASCII数据),事实上void *
在这方面可能更加明确。 / p>
然后我当然会将此指针的地址作为第三个arg传递给glShaderSource
。
我认为只要对GLchar**
进行C风格的演员是安全的,事实上这可能是这种情况的标准答案。使用reinterpret_cast
只会超越,但不可否认只是少量。
但是我想知道在这种情况下思考过程应该是什么。 为什么正是因为我能够在这里驳回这些角色的签名?是不是因为我不期望写一个在任何字符上设置高位的着色器,这意味着我可以投射它?
如果我遇到有符号/无符号整数的情况怎么办?虚假的负整数值真的会被解释为大的正值?我怎样才能在这里编写代码以确保"安全"关于它?
我的直觉告诉我,如果没有实现实际执行的代码并观察数据本身而不是传递指针,这显然是不可能的,所以在这种情况下,没有办法重新获得static_cast
的安全性,因为我被迫使用指针。
答案 0 :(得分:8)
您需要使用reinterpret_cast
甚至在char *
和unsigned char *
之间进行转换。 (有或没有const)。这是因为您将存储为一种类型的位视为不同类型的位;而static_cast
则用于进行价值转换。
正如WhozCraig所指出的,在char **
和unsigned char **
之间进行转换实际上是将一个指针作为另一个指针类型别名(因此,也需要reinterpret_cast
)。
这在理论上可能都是一个问题,但就实际考虑(IMO)而言,你必须付出的努力才能支持所有可能性,这太麻烦了;对于所有意图和目的,您可以假设将char
别名unsigned char
给出与值转换相同的结果,对于两种指针类型也是如此。
答案 1 :(得分:1)
如果您使用static_cast
中间件,则可以使用void*
完全转换:
unsigned char* src = ...; // your input
char* srcChar = static_cast<char*>(static_cast<void*>(src));
glShaderSource(..., &src, ...);
我不会说它比reinterpret_cast
更好,但至少它表明reinterpret_cast
并非绝对必要。