Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC's implementation of angle-brackets includes. Why does it have to be as described below?

This document in its section 2.6 Computed Includes has the following paragraph:

If the line expands to a token stream beginning with a < token and including a >  token, then the tokens between the <  and the first > are combined to form the filename to be included. Any whitespace between tokens is reduced to a single space; then any space after the initial < is retained, but a trailing space before the closing > is ignored. CPP searches for the file according to the rules for angle-bracket includes.

I know this is implementation defined, but why does it have to be this way for GCC? I'm referring specifically to the highlighted sentence above.

EDIT

I have just noticed that the third paragraph before the one quoted above says the following:

You must be careful when you define the macro. #define saves tokens, not text. The preprocessor has no way of knowing that the macro will be used as the argument of #include, so it generates ordinary tokens, not a header name. This is unlikely to cause problems if you use double-quote includes, which are close enough to string constants. If you use angle brackets, however, you may have trouble.

Does anyone know what kind of trouble is being pointed out here?

like image 728
Ayrosa Avatar asked Apr 24 '20 21:04

Ayrosa


People also ask

When we include the header file in the angle brackets the compiler searches for it in?

angular brackets are used for global use of the header files which are predefined and we include in our program. When you use angle brackets, the compiler searches for the file in the include path list. Angular brackets are used for standard inclusions.

What are angled brackets?

An angle bracket or angle brace or angle cleat is an L-shaped fastener used to join two parts generally at a 90 degree angle. It is typically made of metal but it can also be made of wood or plastic. The metallic angle brackets feature holes in them for screws.


1 Answers

I guess the implementor chose the simplest way when they implemented this functionality, without giving it much thought.

It seems that the initial implementation landed in 2000-07-03 (two decades ago!). The relevant part looks like (source):

  for (;;)
    {
      t = cpp_get_token (pfile);
      if (t->type == CPP_GREATER || t->type == CPP_EOF)
        break;

      CPP_RESERVE (pfile, TOKEN_LEN (t));
      if (t->flags & PREV_WHITE)
        CPP_PUTC_Q (pfile, ' ');
      pfile->limit = spell_token (pfile, t, pfile->limit);
    }

Notably, it breaks out when it sees the CPP_GREATER token (i.e. >), before reserving memory for the token. This makes sense, since there's no need to allocate memory when the token will not be written to the buffer.

Then, only after memory is reserved, the preprocessor checks whether the token has preceding whitespace (t->flags & PREV_WHITE) and when it does, writes a whitespace character to the buffer.

As a result, in < foo / bar >, only the whitespaces before foo (that is, after the initial <), /, and bar are kept.

like image 167
cpplearner Avatar answered Oct 17 '22 20:10

cpplearner