Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preprocessor conditional distributed across `#include` files

Is this legal?

foo.h:

    #if 1
    #include "bar.h"

bar.h:

    #endif

foo.c

    #include "foo.h"

clang-700.1.81 complains in a kind of a funny way:

    In file included from foo.c:1:
    In file included from ./foo.h:2:
    ./bar.h:1:2: error: #endif without #if
    #endif

(which means like it did #include "bar.h")

    # 3 "./foo.h" 2
    In file included from foo.c:1:
    ./foo.h:1:2: error: unterminated conditional directive
    #ifndef FOO

(which means like it didn't #include "bar.h").

I have an uneasy feeling that the preprocessor cares about more than a Standard mandates it to. Please correct me if I am wrong, or prove otherwise if I am right.

like image 945
user58697 Avatar asked Oct 24 '16 06:10

user58697


2 Answers

It is not legal. All of the conditional directives which make up the conditional section must be in the same file, although the conditional groups may contain #include directives or nested conditional sections.

This constraint is made explicit by the grammar for preprocessing files (§ 6.10).

      preprocessing-file:
               group opt
      group:
               group-part
               group group-part
      group-part:
               if-section
               control-line
               text-line
               # non-directive
      if-section:
               if-group elif-groups opt else-group opt endif-line

The constraint is also implicit in §5.1.1.2 paragraph 4 which describes the functioning of the #include directive as a recursive execution of phases 1 through 4, rather than a simple textual inclusion:

A #include preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively.

like image 51
rici Avatar answered Oct 12 '22 13:10

rici


Interesting question. I think this is answered by the C11 standard in two places.

First we look at the grammar in §6.10, it's obvious that the #if and #endif must be in the same preprocessing-file. If the name itself of wasn't enough, we can look at §5.1.1.1 for the definition:

5.1.1.1 Program structure

1 A C program need not all be translated at the same time. The text of the program is kept in units called source files, (or preprocessing files) in this International Standard. A source file together with all the headers and source files included via the preprocessing directive #include is known as a preprocessing translation unit

like image 39
Art Avatar answered Oct 12 '22 13:10

Art