Search code examples
cgcccode-generationpragma

understanding GCC dependency pragma directive


I was exploring gcc supported pragmas and I just didn't get what the manual say about #pragma GCC dependency:

#pragma GCC dependency allows you to check the relative dates of the current file and another file. If the other file is more recent than the current file, a warning is issued. This is useful if the current file is derived from the other file, and should be regenerated. The other file is searched for using the normal include search path. Optional trailing text can be used to give more information in the warning message.

Can anyone explain this part with some minimal code?

This is useful if the current file is derived from the other file

How can the current file be derived from the other file? I can understand how another file can be derived form the current file but not vice versa.


Solution

  • How can the current file be derived from the other file? I can understand how another file can be derived form the current file but not vice versa.

    The primary case served is when a C source file is created by a program, using the designated other file as an input. The C source is derived from the other file by running the program. It is to be presumed that differences in the other file would cause the code generator program to produce the C file differently, at least a little, else the pragma in question would not be used.

    Thus, if the designated other file's last-modification timestamp is more recent than the C file's, then it is highly suspect to be compiling the C file at all, for it probably does not correspond to the current version of the other file. Instead, one should regenerate the C source from the other file by running the code generator program again, obtaining a whole new version of the C file to replace the current one. The new one will, of course, have a last modification timestamp newer than the other file's, because the other file had to exist before the new version of the C file could be generated from it.

    Example:

    There is a classic program named lex whose purpose is to help write programs that process text, especially the text of programming languages or rich data languages (the details are not important). The input file for this program describes how to recognize and categorize the basic units of this language, which are called "tokens". If the language being parsed were C, then tokens would include language keywords, numeric constants, and operators. The input file for lex is typically tens of lines long.

    lex reads such an input file and writes a C source file defining several functions and some internal tables that implement the "scanning" behavior required: reading the input text and breaking it up into tokens, which it reports back to its caller. The C source generated by this program is typically a few thousand lines long, which, compared to the much smaller input file, explains in a nutshell why lex is useful.

    To build a program that scans the language in question, one provides functions (in a different source file) that call those generated by lex, and compiles them along with the lex-generated C source to obtain a complete program. Say the lex input file is named language.l, and the output of running lex on that file is named language.c. If I want to change the behavior of the scanner functions then the thing to do is to modify (small, simple) language.l and then re-run lex to regenerate language.c.

    When I change language.l in any meaningful way, language.c becomes out of date until I generate a new version of it from language.l by re-running lex. If I compile the outdated version of language.c then the result does not reflect the current version of language.l. This usually constitutes an error on the part of the person building the program, and #pragma GCC dependency provides a mechanism for eliciting a warning from the compiler in that situation.