Reputation: 648
#include <stdio.h>
enum class TEST_ENUM{
VALUE =1,
};
int main( ){
// Gcc will warn.
printf("%u", TEST_ENUM::VALUE);
// Both clang and gcc are happy.
printf("%u", uint32_T(TEST_ENUM::VALUE));
}
In the above example, gcc will emit the following diagnostic:
<source>:8:12: warning: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'TEST_ENUM' [-Wformat=]
printf("%u", TEST_ENUM::VALUE);
Regardless of compiler version or warnings enabled, I cannot seem to get clang to emit that same diagnostic. Since this is a warnning and not an error, I assume both are standards compliant. Why does gcc complain when clang won't? Is gcc being overly cautious here, or is there actually something worth warning about?
Upvotes: 0
Views: 324
Reputation: 122585
From cppreference:
... - arguments specifying data to print. If any argument after default conversions is not the type expected by the corresponding conversion specifier, or if there are fewer arguments than required by format, the behavior is undefined. If there are more arguments than required by format, the extraneous arguments are evaluated and ignored
Is gcc being overly cautious here, or is there actually something worth warning about?
Not at all overly cautios. You are passing a parameter of wrong type!
Since this is a warnning and not an error, I assume both are standards compliant. Why does gcc complain when clang won't?
When your code has undefined behavior then compilers are not required to issue any diagnostics. GCC is just being nice to you here.
If you are forced to use a type-unsafe API you can always wrap it into something type-safe :
void Log(const TEST_ENUM& x) {
the_actual_logging_api( "%u", static_cast<std:underlying_type<TEST_ENUM>>(x));
}
Upvotes: 3