Currently, I have the following piece of code:
enum class Letters {
A,
B,
C
};
#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wswitch"
Letters e(Letters::A);
switch(e){
case Letters::A: break;
case Letters::B: break;
}
#pragma GCC diagnostic pop
I want to use something like this:
class DiagnosticError {
public:
constexpr DiagnosticError() {
#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wswitch"
}
constexpr ~DiagnosticError() {
#pragma GCC diagnostic pop
}
};
enum class Letters {
A,
B,
C
};
{
constexpr DiagnosticError switchError;
Letters e(Letters::A);
switch(e){
case Letters::A: break;
case Letters::B: break;
}
}
The code compiles fine under C++20, but without generating the error:
error: enumeration value 'C' not handled in switch [-Werror=switch]
38 | switch(e){
Why is that? Is it possible to achieve what I want?
Pragmas are handled by too early a translation phase to apply something like a guard object to a block. The best you can do is write your macros to cut a bit on the boiler-plate
Since C++11 we have the
_Pragmaform of the directive, to embed pragmas into other expansions.DIAG_ERR_PUSH(...)takes the place of your guard object, andDIAG_POP()delimits the region (instead of curly braces).Not quite RAII, but sure better than having to type all the minutia for the pragma. Here's a live example.