C++ 将C字符串强制转换为无符号字符指针

C++ 将C字符串强制转换为无符号字符指针,c++,casting,C++,Casting,我正在使用大量字节编译一个低级代码。在某些情况下,我可以方便地使用双引号括起来的旧C字符串来定义 但当使用gcc或g++编译时(不知道其他编译器的行为),它总是以尖字符串的符号困扰着我 基本上当我写这个的时候 const unsigned char & refok = *"ABCDEFGHI"; 编辑:好的,上面的代码并没有像理论上那样工作,只是保留了对字符串第一个字符副本的引用。由于优化,它实际上允许使用某些编译器访问所有字符串,但可能随时中断 还是这个 const unsigned

我正在使用大量字节编译一个低级代码。在某些情况下,我可以方便地使用双引号括起来的旧C字符串来定义

但当使用gcc或g++编译时(不知道其他编译器的行为),它总是以尖字符串的符号困扰着我

基本上当我写这个的时候

const unsigned char & refok = *"ABCDEFGHI";
编辑:好的,上面的代码并没有像理论上那样工作,只是保留了对字符串第一个字符副本的引用。由于优化,它实际上允许使用某些编译器访问所有字符串,但可能随时中断

还是这个

const unsigned char oktoo[10] =
    {'A','B','C','D','E','F','G','H','I',0};
编译器什么也没说

但它肯定会拒绝这一点:

const unsigned char * bad = "ABCDEFGHI";
带着信息

error: invalid conversion from 
   ‘const char*’ to ‘const unsigned char*’
   [-fpermissive]
这甚至不是警告,而是一个错误

我想知道为什么这个问题比使用引用或将单个字符从有符号字符转换为无符号字符更严重?还是我遗漏了什么?

我想你遗漏了很多东西

第一行可能与您的想法完全不同。(它涉及到临时设备的转换和寿命延长。)

第二行初始化大括号初始化器中相应字符中的每个无符号字符

在第三行中,编译器是正确的:字符串文本的类型为
const char*
,通常不能将
T*
转换为
U*


请注意,该标准明确要求
char
unsigned char
signed char
是不同的类型。这里的理由是,
char
应该是平台的本机字节类型,而另外两个是显式无符号和有符号整数类型。无符号/有符号类型用于代数运算,而无符号类型用于与系统接口(例如命令行参数和文件I/O)。

允许数字类型之间进行隐式转换;这就是前两个正在做的事情。不允许在不同指针类型之间进行隐式转换(除了将派生类指针转换为基类指针之外)

请注意,第一个字符不引用数组的第一个字符。它创建该字符的临时副本,转换为类型
unsigned char
,并将引用绑定到该字符,将临时字符的生存期延长到引用的生存期

第二个将初始化器列表中的每个
char
转换为
无符号char
数组元素


第三个尝试将
常量字符*
转换为
常量无符号字符*
;由于
char
unsigned char
是不同的类型,因此不允许隐式指针转换。

。使用
reinterpret\u cast
绕过它有多安全?我想没关系。类型双关规则明确免除了所有风格的字符指针。(请确保保持常量,但您已经这样做了。)事实上,我一直都在这样做,因为我希望我的数据是
无符号字符
,但我确实从文件中读取并写入到文件中。@kris:再次读取:本机类型没有签名,它是未指定的,并且取决于平台。所有的标准要求是这三种字符类型是不同的,因此它们的指针是不兼容的。关于标准要求,除了“语言就是这样要求的”之外,没有什么可以说的了。原生字符不是显式签名或未签名的。使用const signed char*bad=“ABCDEFGHI”时会出现相同的错误;这是一种“可能被签署,这不关你的事”的字符。@kris:。。。这就是说,类型(不是它们的指针!)是可转换的,任何整型类型都是可转换的。当然,你必须注意签名问题。例如,如果值太大,将无符号字符转换为有符号字符可能是未定义(而不仅仅是未指定)的行为;而将有符号转换为无符号始终是定义良好的。这应该能真正解释你观察到的一切,但请随意提出更具体的问题。好吧,我猜第一个版本只是假的,只有在访问后续字符时才有效,因为编译器正在优化临时字符的重新分配。这绝对应该避免。从今以后,如果我想用无符号字符来表示一组数据,我就只能用合成噪声来解决。你的问题是C++和C++对一个C和C++有很大差异的话题的标记。请删除你不使用的语言的标签。@复杂的SeBiBig,因为看起来他不急于做这件事,你可以只加C答案,解释是C而不是C++(就像我所接受的答案一样,我相信)。正如任何人都可以看到上面提到的虚假引用,我的建议是用C++编写的。我的问题是,当用C编译时,完全相同的代码是有效的,而使用C++时,编译错误是有效的。