不允许从"常量无符号字符*常量*"到"常量字符*常量*"static_cast



我遇到的是我的编译器拒绝将我的无符号字符指针转换为有符号的字符指针。我困惑了一会儿,因为我使用static_cast转换符号的时间最长

然后我做了一点挖掘(嗯,它不是很深。我做了一点舀!即使现在我明白static_cast阻止指针类型转换正是为什么它是更安全、更好的转换方式(比可能调用实现定义行为或未定义行为的传统替代方案)的原因,我仍然不确定我应该为我的情况做些什么。

我在这里是对OpenGL API函数的调用,其签名是

void glShaderSource(
    GLuint shader, GLsizei count, const GLchar **string, const GLint *length
);

我最近更改了文件读取器 API,以便我现在使用 unsigned char * 来代替从文件中读取的数据作为char *返回。此更改不是错误的,因为我觉得无符号字符对原始数据(即使它很可能是 ASCII 数据)的处理要好得多,事实上void *在这方面可能更清楚。

然后当然,我会将此指针的地址作为第三个参数传递给glShaderSource

我认为对我来说,只做 C 式演员表来GLchar**是安全的,事实上这可能是这种情况的标准答案。使用reinterpret_cast只会超越,但不可否认的是,这只是一小部分。

但我想更多地了解在这种情况下的思维过程应该是什么。为什么我能够在这里驳回有关字符的签名?仅仅是因为我不希望编写一个在其任何字符上设置高位的着色器,这意味着我可以强制转换它吗?

如果我遇到有符号/无符号整数的情况,并且确实存在虚假负整数值被解释为大正值的可怕后果怎么办?我如何在这里编写代码以尝试"安全"?

我的直觉告诉我,如果不实现实际去观察数据本身而不是传递指针的代码,这显然是不可能的,所以在这种情况下没有办法重新获得static_cast的安全性,因为我被迫使用指针。

您需要

使用 reinterpret_cast 甚至在 char *unsigned char * 之间进行转换。(有或没有常量)。这是因为您将存储的位视为一种类型,视为不同类型的位;而static_cast用于进行价值转换。

正如 WhozCraig 指出的那样,在 char **unsigned char ** 之间进行转换实际上是将一个指针别名为另一种指针类型(因此,也需要 reinterpret_cast )。

这在理论上可能都是一个问题,但就实际考虑(IMO)而言,您必须付出的努力来支持所有可能性的时间太麻烦了;对于所有意图和目的,您可以假设别名charunsigned char给出与价值转换相同的结果, 对于两种指针类型也是如此。

如果您使用void*中间,则可以完全使用 static_cast 进行转换:

unsigned char* src = ...;  // your input
char* srcChar = static_cast<char*>(static_cast<void*>(src));
glShaderSource(..., &src, ...);

我不会说它比reinterpret_cast更好,但至少它表明reinterpret_cast不是绝对必要的。

最新更新