以下代码在GCC上编译时没有警告,但在Visual Studio 2005中发出警告。
const void * x = 0;
char * const * p = x;
x指向未知类型的常量对象,p指向char的常量指针。为什么p的赋值会导致警告?
同样,这是C,而不是C ++。感谢。
答案 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
像男人一样放在右边。