0

There are at least three different posts about how void pointer arithmetic is prohibited in C; that gcc 4.8.2 allows it, assuming that a void is of byte size; and how one can turn on extra pedantic warnings to trigger an error. Here is an example:

#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;
}

My question is about thinking about what a C compiler is supposed to do in case of invalid code. Is it not considered a bug when a compiler does not issue a compile error on invalid code?

And this seems like bizarre behavior for a compiler, anyway — even if gcc does not issue a compile error, at the very least, it could issue a "deprecated" warning with the default compiler flags. And, even with -Wall, it is still not even giving a warning. Huh? It surprised me because gcc seems very mature otherwise and C is not exactly a novel or complex language.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
ivo Welch
  • 2,427
  • 2
  • 23
  • 31
  • Did you try `-pedantic`? – Shafik Yaghmour Aug 19 '14 at 03:25
  • http://stackoverflow.com/a/13113325/391161 – merlin2011 Aug 19 '14 at 03:27
  • Both `gcc` and `clang` [warn when you are using extensions by using the -pedantic flag](http://stackoverflow.com/questions/22285043/forcing-compiler-to-c99-standard/22285657#22285657) and you can use the `-pedantic-errors` flag to turn them into errors. – Shafik Yaghmour Aug 19 '14 at 03:35
  • Mainly because GCC developers consider it a feature that is beneficial. – Jonathan Leffler Aug 19 '14 at 04:16
  • guys, this is *not* the same question. and whoever gave it a '-1', did not read my question. I stated upfront that the void* question was answered. the question was whether this makes gcc a non-compliant compiler in its default configuration. – ivo Welch Aug 22 '14 at 15:48

3 Answers3

12

The C standard makes an attempt to perform pointer arithmetic on void* a constraint violation, which means that any conforming C compiler must issue at least one diagnostic message for any program containing such an attempt. The warning may be a non-fatal error; in that case, the compiler may then go on to generate code whose behavior is defined by the implementation.

gcc, by default, does not warn about pointer arithmetic on void*. This means that gcc, by default, is not a conforming C compiler.

One could argue that this is a bug, but in its default mode gcc is not a compiler for standard C but for GNU C. (A Fortran compiler's failure to be a conforming C compiler is also not a bug.)

Carefully chosen command-line options can force gcc to at least attempt to be conforming. For example:

gcc -std=cXX -pedantic

where XX is one of 90, 99, or 11, will cause gcc to warn about pointer arithmetic on void*. Replacing -pedantic with -pedantic-errors causes it to treat such arithmetic as a fatal error.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • 1
    2 cents: Key take-away from this post is: GCC doesn't compile standard C, by default. For portability, I like to use **-ansi -pedantic -Wall -Wextra -Werror** and then loosen it up if I need features/behaviour not present in C89 and if GCC gives me grief about something which ought to be fine by C89 and which is intentional. – Shao Aug 19 '14 at 04:24
2

Sure invalid standard C code could be legal in a specific compiler, it's called compiler extension.

It's true in this case, from https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html

In GNU C, addition and subtraction operations are supported on pointers to void and on pointers to functions. This is done by treating the size of a void or of a function as 1.

If you need your code to be portable, it's always a good idea to stick with standard C, but if your code runs only on a specific platform, it's no harm to use certain compiler extensions.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • 1
    Extensions are permitted, but a conforming compiler still must issue diagnostic when required. Pointer arithmetic on `void*` requires a diagnostic. – Keith Thompson Aug 19 '14 at 03:36
0

C11 standard n1570 S6.5.6/2:

For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to a complete object type and the other shall have integer type. (Incrementing is equivalent to adding 1.)

The language for C++ is similar.

It's definitely not standards-conforming behaviour. I think the GCC team already know that.

The answer is that a compliant compiler should issue a diagnostic, and then generate whatever code it likes (or not).

david.pfx
  • 10,520
  • 3
  • 30
  • 63