【问题标题】:Invalid conversion from unsigned char* to char*从 unsigned char* 到 char* 的无效转换
【发布时间】:2013-02-09 08:50:34
【问题描述】:

这是一个代码 -

  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]

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

考虑到 char 类型在 x86 上是 unsigned char -

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

另外,C = U 是否应该在不需要强制转换的情况下成功?

【问题讨论】:

  • 你熟悉"strict aliasing"这个词吗?
  • 阅读那些东西......
  • -fpermissive 可以帮助你,忽略这个烦恼。有时您可能想再次暂时删除该标记,并查看您的编译器是否在您的项目中发现了其他您应该担心的错误。
  • 另外请注意,如果您不想使用编译器标志,您可以通过使用void*s 来做到这一点。例如void* pc; 将允许这种情况发生,而要取消引用您必须执行*((char*)pc)。或者,您可以只使用中间人技术,而不必在取消引用时为 (char*)pc 操心,例如 void* pc_; pc_ = pusc; pc = pc_;,代价是堆栈中不必要的 sizeof(ptr) 字节。

标签: c++ char signed unsigned-char


【解决方案1】:

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

1 .空指针常量是整数类型的整数常量表达式 (5.19) 纯右值,其计算结果为零或 std::nullptr_t 类型的纯右值。空指针常量可以转换为指针类型;结果是该类型的空指针值,并且可以与对象指针或函数指针类型的所有其他值区分开来。这种转换称为空指针转换。相同类型的两个空指针值应比较相等。将空指针常量转换为指向 cv 限定类型的指针是一次转换,而不是指针转换后跟限定转换 (4.4) 的顺序。整数类型的空指针常量可以转换为 std::nullptr_t 类型的纯右值。 [ 注意:生成的纯右值不是空指针值。 ——尾注]

这无关紧要,因为这里没有nulltptr_t 类型的空指针。

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

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

3 .类型“指向 cv D”的纯右值,其中 D 是类类型,可以转换为类型“指向 cv B”的纯右值,其中 B 是 D 的基类(第 10 条)。如果 B 是D 的不可访问(第 11 条)或模棱两可的(10.2)基类,需要这种转换的程序是格式错误的。转换的结果是指向派生类对象的基类子对象的指针。空指针值转换为 目标类型的空指针值。

signed char 不是char 的基类,所以这也不适用。

因此,无法执行从 signed charchar 的隐式标准指针转换。

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

【讨论】:

  • 我认为,需要强调的是,charunsigned charsigned char 是 3 种不同的类型。我怀疑这个问题来自一个误解,即char 要么是signed char 要么是unsigned char
【解决方案2】:

C++没有自动指针转换,赋值两边的指针类型是什么无关紧要,如果它们不同,则需要强制转换。

【讨论】:

    【解决方案3】:

    char 是与 unsigned charsigned char 不同的类型。它只保证具有与其中一个等效的值表示,但它仍然是一种不同的类型。因此,您不能从unsigned char*signed char* 转换为char*(也就是说,除非您使用reinterpret_cast)。 C++ 只是不允许像这样在不同类型之间进行指针转换,因为这样一种类型可能会伪装成另一种类型。

    但是,从unsigned charsigned charchar 的转换非常好,因为它只涉及其值的转换。

    这样考虑:您可以将int 转换为float,但您不能将int* 转换为float*

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2023-04-01
        • 1970-01-01
        • 2016-07-25
        • 2012-04-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-21
        • 1970-01-01
        相关资源
        最近更新 更多