0

The following code causes an error in Green Hills C compiler (error: type int * is incompatible with argument type const int*), while it only produces a warning and compiles with gcc (warning: passing argument 1 of ‘func’ discards ‘const’ qualifier from pointer target type).

void func1(int* a)
{
  (*a)++;
}

const int g = 100;

void func2(void)
{
  func1(&g);
}

Which behavior is according to C standard?

mrn
  • 959
  • 5
  • 15

2 Answers2

4

The call to func1(&g) is invalid. It is a constraint violation in C language, i.e. it is what in everyday terminology is usually referred to as an "error". C language does not support implicit conversion of const int * value to int * type.

The fact that it is "just a warning" in GCC does not mean anything. Use -pedantic-errors switch in GCC to make it report constraint violations as "errors". Green Hills C compiler, as you observed yourself, reports it as an "error" without any help from your side.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • The C standard does not differentiate between warnings and errors. There are only "diagnostics" required for certain violations. It also does not enforce what the compiler does in case of a violation. It all invokes UB. – too honest for this site Dec 16 '16 at 19:55
  • @Olaf: Firstly, C standard defines the concept of between *constraint violation*. The term "error" is often [semi-]informally used as a synonym for *constraint violations*. That's why I took it in quotes and that is how I used in my answer. Secondly, not every warning issued by the compiler is an indication of constraint violation. – AnT stands with Russia Dec 16 '16 at 19:57
  • In C actually most warnings are errors - in the sense they may cause problems in some implementation. The same for OPs code: there will be no problem on environments which store `const` qualified objects in modifyable RAM. – too honest for this site Dec 16 '16 at 20:00
  • @Olaf: "In C actually most warnings are errors" - this actually makes no sense. C itself does not have "warnings" or "errors". Only specific compilers do. – AnT stands with Russia Dec 16 '16 at 20:05
  • In default configuration of GCC, some warnings are actually mandatory diagnostic messages indicating constraint violations, and other warnings are just... warnings that do not indicate any error. In it important to be able to tell the former from the latter. The former group should always be treated seriously. The latter - not so much, especially considering that it contains many genuinely stupid warnings. In this case we are dealing with a "warning" from the first group. So yes, it indicates an error that has to be fixed. – AnT stands with Russia Dec 16 '16 at 20:07
  • Which default warning of gcc do you have in mind which is guaranteed to never cause aproblem on any target architecture? General recommendation is not to ignore **any** warning, but e.g. to inspect it and take measures, e.g. a **well understood** cast. – too honest for this site Dec 16 '16 at 20:08
  • "In C actually most warnings are errors" - I referred to your usage of that term. My first comment should have made clear I was not talking about the C standard, but a specific compiler. And as you mention gcc, I thought it was obvious which implementation I refer to. – too honest for this site Dec 16 '16 at 20:10
  • @Olaf: Default warnings in GCC is changing all the time. I remember there was a period when `-Wmissing-braces` was enabled by default. – AnT stands with Russia Dec 16 '16 at 20:14
  • Well, ok, that might have been true. But then, gcc has evolved over the years and it can be seen stable. In general, it is gopod advice for a beginner to trreat every one of the default, plus `-Wall` `-Wextra` as serious and fix the code. After all even `-Wmissing-braces` can easily be silenced and it won't hurt to (it might in fact avoid common logical errors in beginner's code). – too honest for this site Dec 16 '16 at 20:53
1

Which behavior is according to C standard?

Both compiler behaviors conform with the standard. As @AnT already explained, the call func1(&g) violates a language constraint. The standard's requirement on the compiler in such a case is expressed by paragraph 5.1.1.3/1:

A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint [...]

As you can see, @Olaf is right that the standard does not distinguish different categories of diagnostics. That's an invention and convention of implementations, which generally distinguish between the two based on whether the situation is fatal to the compilation process. The standard has nothing further to say about what a compiler should do so when a constraint violation is detected, however, neither in general nor in this particular case, so it does not even indirectly dictate whether a "warning" or "error" should be emitted.

If the compiler does continue and eventually produces an executable, then the whole resulting program exhibits undefined behavior if at any point in its run it evaluates the problematic function call. This is a reason why a compiler might choose not to emit such a binary (i.e. might consider the constraint violation an "error"), but, again, the standard does not provide any guidance there.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157