Am I paranoid...
- Am I paranoid to want the code to be protected against slicing in interfaces? (I believe I'm not, but one never knows...)
Isn't this a risk management issue?
- do you fear that a bug related to slicing is likely to be introduced?
- do you think it can go unnoticed and provoke unrecoverable bugs?
- to what extent are you willing to go to avoid slicing?
Best solution
- What is the best solution among the ones above?
Your second solution ("make them protected") looks good, but bare in mind that I am not a C++ expert. At least, the invalid usages seem to be correctly reported as errorneous by my compiler (g++).
Now, do you need macros? I would say "yes", because even though you don't say what is the purpose of the guideline you are writing, I guess this is to enforce a particular set of best practices in your product's code.
For that purpose, macros can help detect when people effectively apply the pattern: a basic filter of commits can tell you whether the macro was used:
- if used, then the pattern is likely to be applied, and more importantly, correctly applied (just check that there is a
protectedkeyword), - if not used, you can try to investigate why it wasn't.
Without macros, you have to inspect whether the pattern is necessary and well-implemented in all cases.
Better solution
- Is there another, better solution?
- Slicing in C++ is nothing more than a peculiarity of the language. Since your are writing a guideline (esp. for newbies), you should focus on teaching and not just enumerating "coding rules". You have to make sure that you really explain how and why slicing occurs, along with examples and exercices (don't reinvent the wheel, get inspiration from books and tutorials).
For example, the title of an exercise could be "http://programmers.stackexchange.com/questions/235674/what-is-the-pattern-for-a-safe-interface-in-c?"
So, your best move would be to ensure that your C++ developpers understand what is going on when slicing occurs. I am convinced that if they do, they won't make as many mistakes in the code as you'd fear, even without formally enforcing that particular pattern (but you can still enforce it, compiler warnings are good).
- Pure virtual classes, as others pointed out.
About the compiler
You say :
I have no power on the choice of compilers for this product,
Often people will say "I don't have the right to do [X]", "I'm not supposed to do [Y]...", ... because they think this is not possible, and not because they tried or asked.
It is probably part of your job description to give your opinion regarding technical issues; if you really think the compiler is the perfect (or unique) choice for your problem domain, then use it. But you also said "pure virtual destructors with inline implementation is not the worst choking point I've seen"; from my understanding, the compiler is so special that even knowledgeable C++ developpers have difficulties using it: your legacy/in-house compiler is now technical debt, and you have the right (the duty?) to discuss that issue with other developpers and managers.
Try to assess the cost of keeping the compiler vs. the cost of using another one:
- What does the current compiler brings you that no other one can?
- Is your product code easily compilable using another compiler? Why not?
I don't know your situation, and in fact you probably have valid reasons to be tied to a specific compiler. But in the case this is just plain inertia, the situation won't ever evolve if you or your coworkers don't report productivity or techical debt problems.