I always thought, the preprocessor is independent of C code, so I can put preprocessor statements wherever I want?
This is true of most preprocessor directives, given a not-too-strict interpretation of "can" and "wherever", but it is not true of pragmas in general.
We have to classify pragmas into two categories:
Those in which the first preprocessor token after the initial pragma is STDC.
The spec defines several specific variations on pragmas of this form, and demands that no other pragmas of this form appear. All of these have the same limitation on where they can appear. Taking #pragma STDC FP_CONTRACT ON as an example, C24 7.12.3/2 says:
Each pragma can occur either outside external declarations or preceding all explicit declarations and statements inside a compound statement
That should be read as a restriction, else it would be meaningless. It is thus a fairly strong constraint on where such pragmas can appear.
It is also, therefore, somewhat problematic, in that the C translation model (C24 5.2.1) has the effects of pragmas being applied during translation phase 4 (and the pragmas then being removed, along with all other preprocessing directives), but the boundaries of declarations and statements are not determined until phase 7. The language spec leaves it to implementations to sort that out.
All other pragmas.
One of these ...
causes the implementation to behave in an implementation-defined manner.
(C24 6.10.8/1)
That leaves behavior wide open, as long as the implementation defines it, and explicitly (not quoted) allows for the compiler to reject the program. Since C requires compilers to be restrictive about where group (1) pragmas appear, it should not be too surprising if they are equally restrictive about where others can appear. "Implementation defined" gives compilers license to do so.
So is the problem here that I have the #pragma message in between initializing fields of a structure?
The diagnostic seems to indicate so, and I anticipate that lifting the #pragma directive out of the definition of example would satisfy the compiler. You'll have to try and see, or rely on someone else who already has done so, or on someone familiar with GCC's implementation, because that pragma is documented in the GNU C Preprocessor Manual, and neither that manual nor GCC's speaks at all to where pragmas can appear.
there is no problem using #if etc in between fields of a structure, as the above example shows if you comment the #pragma message line ?!
Correct. Pragmas are weird, and best avoided. All other preprocessing directives have well defined effects that are limited to the preprocessing token stream and the preprocessing of it, and no implementation I know of limits where in the token stream they can appear relative to the C-language syntactic constructs into which the tokens will later be grouped.
So - is there any way to get this #pragma message to work at the position it is in?
That's a question about GCC, not about the C language itself, but I would think not.
-std=c18 -Werror=strict-prototypesset) an error about the definition (declaration) ofmain. WIth-std=c23, that goes away.