为什么GCC不接受void-pointer算法被认为是一个错误?

ivo*_*lch 0 c gcc pointers ansi

关于C中如何禁止无效指针算术,至少有三篇不同的帖子; gcc 4.8.2允许它,假设void是字节大小; 以及如何打开额外的迂腐警告以触发错误.这是一个例子:

#include <stdio.h>

/* compile gcc -Wall -o try try.c */

int main() {
  char *str="string";
  void *vp= (void *) str;

  ++vp; /* arithmetic on void point.  huh? */

  printf("%s\n", (char*)vp);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是考虑在无效代码的情况下C编译器应该做什么.当编译器不对无效代码发出编译错误时,它不被视为错误吗?

无论如何,这对于编译器来说似乎是奇怪的行为 - 即使gcc没有发出编译错误,至少它可以使用默认编译器标志发出"已弃用"警告.而且,即便如此 -Wall,它仍然没有发出警告.咦?这让我感到惊讶,因为gcc看起来非常成熟,而C并不是一种新颖或复杂的语言.

Kei*_*son 12

C标准使得对执行指针算术尝试void*一个违反约束,这意味着任何符合C编译器必须发出的至少一个诊断消息包含这样的尝试的任何程序.警告可能是非致命错误; 在这种情况下,编译器可以继续生成其行为由实现定义的代码.

默认情况下,gcc不会警告指针算术void*.这意味着默认情况下,gcc 不是符合C的编译器.

有人可能会认为这是一个错误,但在默认模式下,gcc不是标准C的编译器,而是GNU C.(Fortran编译器未能成为符合标准的C编译器也不是错误.)

精心选择的命令行选项可以强制gcc至少尝试符合要求.例如:

gcc -std=cXX -pedantic
Run Code Online (Sandbox Code Playgroud)

其中XX是下列之一90,9911,将导致GCC警告有关指针运算void*.更换-pedantic-pedantic-errors的原因它来治疗这种算法是一个致命的错误.