C中的指针到const转换

时间:2009-10-26 11:51:13

标签: c const

以下代码在GCC上编译时没有警告,但在Visual Studio 2005中发出警告。

const void * x = 0;
char * const * p = x;

x指向未知类型的常量对象,p指向char的常量指针。为什么p的赋值会导致警告?

同样,这是C,而不是C ++。感谢。

6 个答案:

答案 0 :(得分:5)

之所以发生这种情况,是因为当你将一种类型的指针指向另一种类型时,有时会无意中(bug),因此编译器会向你发出警告。

因此,为了告诉编译器您确实打算这样做,您必须进行显式转换,如下所示:

        const void * x = 0;
        char * const * p = (char * const * )x;

P.S。在第一个地方,我写了“大部分时间是无意中完成的”,但当他理所当然地说无效*专门用于此目的时,AndreyT让我重新考虑它。

答案 1 :(得分:3)

C代码有效且符合标准的编译器不应该警告,因为const ness被正确保留,并且void *到任何指针类型(旁边的函数指针)的转换是隐含的。

C ++编译器应该警告隐式转换,但是关于丢弃const限定符的警告是错误的,应该被视为编译器错误。

答案 2 :(得分:0)

如果x指向struct Thing而非char,会怎样?在这种情况下,您将使用未指定的行为进行操作。海湾合作委员会倾向于让你这样做,因为它假设你足够聪明,不会在脚下射击自己,但有充分的理由发出警告。

答案 3 :(得分:0)

您必须从右到左阅读以下内容。
char * const * p = x;

例如:
P指向char类型的const指针。

答案 4 :(得分:0)

const void * x = 0;
char * const * p = x;

起初我假设您打算取x的地址并为此编写代码。然后我决定x指向char []的指针。无论如何,它仍然令人困惑:

#include <stdio.h>
int main()
{
        char s [] = "Hello World!";
        const void * x = s;
        const char * const * const p = (const char * const *)&x;
        printf("%s\n", *p);
/* won't compile
        *p++;      // increments x to point to 'e'
        (**p)++;   // increments 'H' to 'I'
*/
        const char * y = s;
        x = &y;
        const char * const * const q = x;
        printf("%s\n", *q);
/* won't compile
        *q++;
        (**q)++;
*/
        return 0;
}

const声明中char之前的额外p会阻止(**p)++进行编译。但是,在声明const(在GCC中)之前添加的q会为warning: dereferencing ‘void *’ pointer error: increment of read-only location ‘**q’隐藏(**q)++。希望有所帮助,它对我有所帮助: - )

答案 5 :(得分:-2)

warning C4090: 'initializing' : different 'const' qualifiers

您无法将const void投射到char *const甚至char *。通过解除引用p,您现在可以修改*(char *)(*x)。这是关于C中指针的一个鲜为人知的微妙。

p的工作类型为:

char const **p = x;

是的,我把const像男人一样放在右边。