static_cast来自' const unsigned char * const *' to' const char * const *'不被允许

时间:2014-12-29 01:40:41

标签: c++ static-cast

我遇到的是我的编译器拒绝将我的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的安全性,因为我被迫使用指针。

2 个答案:

答案 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并非绝对必要。