8

I know it starts with #, and it follows the preprocessing directives format. But does the preprocessor really care about it? The #pragma pack, #pragma once, and all other directives I know, are all proceeded by compilers. A comment in this question even states that #pragma directive survives the pre-processing stage. So my questions are:

  1. Since #pragma is for compiler, why is it considered a preprocessing directive? Is it just because it starts with #?
  2. Does preprocessor really do something with #pragma?
Lundin
  • 195,001
  • 40
  • 254
  • 396
user239216
  • 327
  • 2
  • 4

3 Answers3

7

Why is #pragma considered a preprocessor directive?

Because the C standard says so. It is specified in the chapter preprocessing directives, C17 6.10.6. Other than that, the standard is intentionally very vague with what #pragma should do, since the whole purpose is to do something compiler-specific. Or in case the pragma isn't recognized - ignore it.

How a certain compiler handles the contents of a pragma internally isn't specified.

Some pragmas obviously need to be pre-processed, notably the kind that enables/disables certain compiler behavior like #pragma warning ... etc. Lots of them must be evaluated during pre-processing or the compiler won't know how to compile the code.

Does preprocessor really do something with #pragma?

Yes, it evaluates it in translation phase 4: "Preprocessing directives are executed, macro invocations are expanded, and _Pragma unary operator expressions are executed."

Please note that having a pre-processor separated from the compiler is mostly a theoretical model. In reality the pre-processor and compiler are often rather tightly integrated with each other.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Pre-processing is specifically a source to source translation before any compilation begins. Therefore `#pragma warning` must *not* be pre-processed, or the compiler will never see it. – OrangeDog Sep 07 '20 at 08:35
  • So `pragma` seems a way to influence compiler behavior, but in contrast to compiler flags, the behavior can be local in the code. For example to pack one structure type but not another – Paul Ogilvie Sep 07 '20 at 08:36
  • @OrangeDog Last sentence of this answer. The pre-processor isn't some magical external entity completely separated from the compiler. – Lundin Sep 07 '20 at 08:39
  • @Lundin it's not theoretical at all, you can run the pre-processor separately, then pass its output to the compiler and it should have the same behaviour. In a normal build they run together to optimise for speed e.g. by doing a single parse, then modifying the ast instead of the source directly. – OrangeDog Sep 07 '20 at 08:40
  • @OrangeDog: `#pragma warning` and `#pragma error`, if supported, are handled during the preprocessing phases, the message is output to the user in the same format as a compiler diagnostic, but it is not necessary to inform the *compiler* about it, beyond the fact that `#pragma error` should stop the compilation process with a non zero status code. – chqrlie Sep 07 '20 at 08:46
  • Re “… the whole purpose is to do something compiler-specific”: Per C 2018 6.10.6, a `pragma` directive without `STDC` does something “compiler-specific” (implementation-defined). A `pragma` directive with `STDC` and `FP_CONTRACT`, `FENV_ACCESS`, or `CX_LIMITED_RANGE` does something defined by the standard. – Eric Postpischil Sep 07 '20 at 11:30
2

#pragma once needs to be dealt with by the preprocessor, beacause its job is to replace include guards in ensuring that a file is included — using the preprocessor directive #include — only once at a given location. #pragma pack, on the other hand, needs to pass through the preprocessor unscathed because it is an instruction to the compiler about how to lay out data in memory.

gspr
  • 11,144
  • 3
  • 41
  • 74
2

To directly answer your questions:

  1. Most pragmas, with the exception of STDC FENV_ACCESS, STDC FP_CONTRACT and STDC CX_LIMITED_RANGE are not part of the C-Standard at all and as such it doesn't really matter whether or not they are "preprocessor directives" or not, the compiler is free to process them in any way it sees fit. For some pragmas it makes sense to process them during the preprocessing stage for others it doesn't. The main idea behind pragmas is that they can potentially influence the compilation process from the preprocessing stage onwards but unlike macros they are not expanded to anything.

  2. Yes, e.g. in the case of #pragma once as explained by other answers. But again, this is implementation specific and not prescribed by the standard.

Peter
  • 2,919
  • 1
  • 16
  • 35