Importing macros is a horrible mistake.

455 views
Skip to first unread message

Stack Machine

unread,
Mar 24, 2014, 7:59:33 AM3/24/14
to mod...@isocpp.org
In current C++, the preprocessor can be run independently of the actual compilation step. If macros can be imported, this is no longer true.

Imagine this simple case:
// module A
#define HELLO "Hello, World!\n"

// module B
import A;

int main()
{
    std
::cout << HELLO;
}
What is going to happen?
  1. The user instructs the compiler to compile module B.
  2. The preprocessor is processing module B.
  3. In order to be able to expand the macro HELLO, it needs to know about module A.
  4. Since 'import' is a directive in the language, it cannot know about that module, the preprocessor is suspended and the parser needs to run.
  5. The parser needs to process module B, which is half-preprocessed.
  6. The parser finds the import directive and invokes the same process for module A.
  7. The preprocessor processes module A.
  8. The parser processes module A.
  9. The preprocessor of module B needs to be resumed to expand the macro.
Oh, and how does the preprocessor in step 3 even know that it has to invoke the parser?
And this is just a *very simple* scenario. How is this mess going to be solved?

If I want to use a macro, then I better know what the body of that macro is. There is no such thing as an implementation detail that needs to be hidden. We already have the tool in place to import macros, it's called "#include".

Just my 2 cents.

James Widman

unread,
Mar 24, 2014, 9:31:49 AM3/24/14
to mod...@isocpp.org


On Tuesday, March 25, 2014, Stack Machine <stackm...@hotmail.com> wrote:
In current C++, the preprocessor can be run independently of the actual compilation step.

[You are referring to  a "preprocess-only" mode, wherein a translator performs translation phases 1 through 4 only. ]

True so far...

 
 If macros can be imported, this is no longer true.

If macros can be imported, that implies a possible future change to phase 4 that you have not yet taken into account.

There is little doubt as to whether it is possible to modify [lex.phases] in such a way that we get this effect. (It can be done.)

There is little doubt as to whether it is possible to implement. (It can be done.)

There IS an open question as to whether it's *desired* because of concerns about migration paths. However, there is also good reason to think that those concerns can be addressed without "import A;" causing an execution during  phase 4. 


We already have the tool in place to import macros, it's called "#include".

Personally, I agree, and I think we can produce wording that agrees with this sentiment, while simultaneously indicating (outside of the International Standard) a migration path where  #include <foo.h> has the effect of an import directive followed by the execution of a subset of phase 4 directives that would normally result from traditonal preprocessing.

Implementors have not yet found issue with this approach to migration, and so it seems viable at this time.

Consequently, I do not currently foresee objection to any modules proposal where the import directive has no effect during phase 4.


Reply all
Reply to author
Forward
0 new messages