问题 从unsigned char *到char *的转换无效


这是一个代码 -

  1 int main(int argc, char *argv[])
  2 {
  3     signed char S, *psc;
  4     unsigned char U,  *pusc;
  5     char C, *pc;
  6 
  7     C = S;
  8     C = U;
  9 
 10     pc = psc;
 11     pc = pusc;
 12 
 13     return 0;
 14 }

$ gcc test.cpp -o a
test.cpp: In function ‘int main(int, char**)’:
test.cpp:10:7: error: invalid conversion from ‘signed char*’ to ‘char*’ [-fpermissive]
test.cpp:11:7: error: invalid conversion from ‘unsigned char*’ to ‘char*’ [-fpermissive]

这是在英特尔32位机器上的Ubuntu 12.10上的gcc版本4.6.3上编译的。

考虑到这一点 char 类型是 unsigned char 在x86上。  -

如果第7行和第8行的非指针类型的赋值为Ok,为什么第10行和第11行的指针类型会抛出错误?

还应该 C = U 成功而不需要演员?


2983
2018-02-23 21:51


起源

你熟悉这个词吗? “严格别名” ? - WhozCraig
读那些东西...... - nightlytrails
-fpermissive 可以帮助你,并忽略这种烦恼。有时您可能需要暂时删除标记,看看您的编译器是否发现了除项目之外的其他错误 应该 担心。 - rsethc
另请注意,您可以通过使用来完成此操作 void*s,如果您不想使用编译器标志。例如 void* pc; 会允许这种情况发生,并且要取消引用你必须这样做 *((char*)pc)。或者你可以使用中间人技术而不必为演员而烦恼 (char*)pc 每当你取消引用时,例如 void* pc_; pc_ = pusc; pc = pc_;,以牺牲不必要为代价 sizeof(ptr) 堆栈中的额外字节数。 - rsethc


答案:


首先,重要的是要强调这一事实 charsigned char,和 unsigned char 都是 不同种类。 C ++ 11 Standard的4.10节定义了不同类型指针之间的三种可能的标准指针转换:

1。空指针常量是整数类型的整数常量表达式(5.19)prvalue,其求值为零或者类型为std :: nullptr_t的prvalue。空指针常量可以转换为指针类型;结果是该类型的空指针值,并且可以与对象指针或函数指针类型的每个其他值区分开。这种转换称为空指针转换。相同类型的两个空指针值应相等。将空指针常量转换为指向cv限定类型的指针是单个转换,而不是指针转换的序列,后跟限定转换(4.4)。可以将整数类型的空指针常量转换为std :: nullptr_t类型的prvalue。 [注意:生成的prvalue不是空指针值。 - 尾注]

这是不相关的,因为我们没有类型的空指针 nulltptr_t 这里。

2。类型为“指向cv T的指针”的prvalue,其中T是对象类型,可以转换为类型为“指向cv void的指针”的prvalue。将“指向cv T的指针”转换为“指向cv void的指针”的结果指向T类型的对象所在的存储位置的开始,就好像该对象是类型T的最派生对象(1.8) (即,不是基类子对象)。空指针值被转换为空指针值   目的地类型。

这不适用,因为目标类型不适用 void。最后,

3。类型为“指向cv D的指针”的prvalue,其中D是类类型,可以转换为类型为“指向cv B的指针”的prvalue,其中B是D的基类(第10节)。如果B是D不可访问(第11条)或模糊(10.2)基类,需要这种转换的程序是不正确的。转换的结果是指向派生类对象的基类子对象的指针。空指针值转换为   目标类型的空指针值。

signed char 不是基类 char,所以甚至不适用。

因此,一个隐式的,标准的指针转换而来 signed char 至 char 无法执行。

另一方面,根据第4.7段中的规定,允许在整数类型的值之间进行转换。


7
2018-02-23 21:57



我认为,重要的是要强调一点 char, unsigned char 和 signed char 有3种不同的类型。我怀疑这个问题来自误解 char 或者是 signed char 要么 unsigned char。 - Maciej Hehl
@MaciejHehl:是的。我编辑了答案,谢谢。 - Andy Prowl


C ++没有自动指针转换,分配的每一侧的指针类型都无关紧要,如果它们不同,则需要转换。


2
2018-02-23 21:55





char是一种独特的类型 unsigned char 和 signed char。它只能保证对其中一个具有等价值表示,但它仍然是一种独特的类型。因此,您无法转换 unsigned char* 要么 signed char* 至 char* (也就是说,除非你使用 reinterpret_cast)。 C ++只是不允许像这样的不同类型之间的指针转换,因为那样一种类型可以伪装成另一种类型。

但是,从任何一个转换 unsigned char 要么 signed char 至 char 完全没问题,因为它只涉及其价值的转换。

以这种方式考虑:你可以转换一个 int 到了 float,但你不能转换 int* 到了 float*


1
2018-02-23 21:55





我可能是错的,但如上所述,当你指定“C = S; C = U;”时,C ++会自动转换它,有点像你做“char x =”h“; printf(”%i“,x );”。但是,指针指向内存中的特定位置,并且该位置具有大小。因此,虽然转换类型仅从不同角度查看值,但指向不同的值可能涉及更改指向的值的大小。


0
2018-02-23 22:01