A few questions about C ++ compilers: GCC, MSVC, Clang, Comeau, etc.

I have few questions about C ++ compilers

  • Are C ++ compilers needed for a single pass compiler ? Does the Standard talk about this somewhere?

  • In particular, is this a single-pass GCC compiler? If so, why does it generate the following error twice in this example (although the template argument in each error message is different)?

    error: declaration 'adder <item> obscures the parameter
    error: declaration 'adder <char [21]> element obscures the parameter

More general question


Useful links:

+6
c ++ gcc compiler-construction visual-c ++ clang
source share
5 answers

The standard does not establish any requirements that have ever occurred in relation to how the compiler is implemented. But what do you mean by "One Pass"? Most compilers today only read the input file once. They create a representation in memory (often in the form of some kind of parsing tree) and can take several passes over it. And almost certainly make a few passes over parts of it. The compiler must make a “pass” over the internal representation of the template each time it is created, for example; there is no way to avoid this. g ++ also does a "walk" through the pattern when it is defined, before the instance reports some errors. (The standard committee developed templates that allow the maximum detection of errors at the point of definition. This is the motivation for typename requirements in certain places, for example.) Even without templates, the compiler will usually have to do two passes over the class definition if there are functions defined in it.

As for the more general question, again, I think, you would have to define exactly what you mean by “one pass”. I don’t know of any compiler today that reads the source file several times, but almost all will visit some or all of the nodes in the split tree more than once. Is it single pass or multi pass? the difference was more significant in the past when the memory was not sufficient to support most of the source code in the internal representation. Languages ​​such as Pascal and, to a lesser degree C, were sometimes designed so that they could be easily implemented with a single skip compiler, since a one-pass compiler would be much faster. Today, this issue is largely irrelevant, and modern languages, including C ++, tend to ignore it; where C ++ seems to fit the needs of a single-pass compiler, this is mainly for C compatibility reasons, and where C compatibility is not a problem (for example, in class definition), it often makes the declaration order inconsequential.

+5
source share

From what I know, 30 years ago, it is important that the compiler be single-pass, because reading and writing to disk (or tape) is very slow and there is not enough memory to store all the code (thanks to James Kanze). In addition, a single pass is required for scripting / interactive languages.

Currently, compilers are usually not single-pass; there are several intermediate representations (for example, Abstract Syntax Tree or Static Form of Single Assignment ) that the code is converted to and then parsed / optimized.

Some elements in C ++ cannot be resolved without any intermediate steps, for example. in a class, you can refer to members that are defined only later in the class. In addition, all the templates must somehow be remembered for further access during instance creation.

What usually does not happen is that the source code is not analyzed several times - this is not necessary. Thus, you should not experience the same syntax error reported multiple times.

+3
source share
  • No, I would be surprised if you find a heavily used compiler with a single C ++ pass.
  • No, it performs several passes and even various optimizations based on the flags that you pass.

Advantages (single pass): fast! Since all source code needs to be studied only after the compilation phase (and, therefore, the start of execution) can happen very quickly. This is also an attractive model because it makes the compiler understandable and often “easier” to implement. (I worked once on the Pascal compiler once, but I don't often see them, while single-pass interpreters are common)

Disadvantages (sinlge-pass): Optimization, semantic / parsing. Sometimes a single code scan allows you to do everything that is easy to catch with simple mechanisms in a few passes. (why do we have things like JSLint)

Advantages (multi-pass): optimization, semantic / parsing. Even pseudo-interpreted languages, such as "JRuby", go through the process of compiling the pipeline to go to the java / jvm bytecode before execution, you could consider this multi-pass, and multiple viewing of various representations (and, therefore, the resulting optimizations) of the code can do it very fast.

Disadvantages (multi-pass): complexity, sometimes time (depending on whether AOT / JIT is used as a compilation method)

In addition, single pass is widely used in academia to help explore aspects of compiler design.

+2
source share

The compiler should only look at the sources when they are from top to bottom, but this does not mean that he does not need to process the analyzed content more than once. In particular, with templates, it must create template code with a type, and this cannot happen until the template is used (or explicitly created by the user), which is the reason for your repeated errors:

When the template is defined, the compiler detects an error, and at that moment the type was not replaced. When the actual instance is created, it replaces the template arguments and processes the result, which causes the second error. Note that if the template was specialized after the first definition and before creating an instance for this particular type, a second error should not occur.

+1
source share

Walter Bright, the developer of the first C ++ compiler, said he considered it impossible to compile C ++ without at least 3 gaps. And, yes, this means that 3 complete text transformations are converted through the source, not just a crawl through the internal tree view. See an article in Dr. Dobb's journal : "Why is C ++ compilation so slow?" Therefore, any hope of finding a true one-pass compiler seems doomed. (I think that was part of the motivation. Bright had to develop D, his alternative to C ++.)

+1
source share

All Articles