In the P1881 proposal, the concept of epochs (on a module level) for the C++ code is proposed. Such functionality can allow customization of the C++ syntaxis and C++ behavior on the level of the module without necessarily breaking backward compatibility. More elaborate motivation is given in the proposal.
Version 1: no epochs, everything compiles fine
module ParticleMovement;
export void move(Particle&, float x, float y);
void moveExample()
{
Particle p{};
move(p, 3.42, 2.49); // OK
}
Version 2: epoch 2023
(with an assumption on disabling implicit conversion in it), code ill-formed:
epoch 2023; // Module-level switch
module ParticleMovement;
export void move(Particle&, float x, float y);
void moveExample()
{
Particle p{};
move(p, 3.42, 2.49); // Compilation error
move(p, 3.42f, 2.49f); // OK, no implicit conversions
}
This definitely looks to be an interesting proposal, and is very different from simply specifying compile switches -std=c++XXX
.
However, I wonder:
#pragma
's, provided compiler support or that would introduce severe technical difficulties (from the implementation or usage point of view) compared to the module-based proposal?Say, something along the line:
#pragma epoch 2023;
export void move(Particle&, float x, float y);
void moveExample()
{
Particle p{};
move(p, 3.42, 2.49); // Compilation error
move(p, 3.42f, 2.49f); // OK, no implicit conversions
}
I have read the proposed mechanism which targets modules-based implementation; however, I do not see why it has to be modules.
Also relevant: a lightning talk at CppCon 2019 of Vittorio Romeo, the author of P1881 proposal
In P1881, the epochs are defined to be a module-level switch. Is there any reason why it has to be on the module level besides convenience? Why not translation-unit level?
Theoretically, epoch-declarations could appear at any level, including block-scope or even library-scope. I chose modules for the first revision of the proposal as they're small enough to allow graceful migrations from an epoch to another for large projects, but also big enough to not have multiple epochs appear in the same source file.
In Belfast, it was suggested that module partitions might be a better choice as they would allow single modules to gradually migrate to a newer epoch.
could this behavior seamlessly achieved via
#pragma
's, provided compiler support or that would introduce severe technical difficulties (from the implementation or usage point of view) compared to the module-based proposal?
In principle, I think that could be possible. Regardless of whether #pragma
s or module-level declarations are chosen, I believe that compiler vendors would still have to perform an humongous amount of work to implement anything like epoch (but I believe it's worth it).
I do not see why it has to be modules.
It doesn't, really. With P1881, I did not only try to invent a mechanism that allows changing the meaning of syntax, but I tried envisioning a mechanism that would fit well in the C++ ecosystem and promote good engineering practices.
I believe that a block-scope declaration or a #pragma
has a lot more opportunities for misuse compared to a module-level one. I also think that tying epochs to modules would help developers think about epoch migration while modularizing existing codebases.
In general, the proposal is still at an early stage, and all of these design decisions might change. Feedback and ideas are always appreciated - the author's email can be found in the paper.