简体   繁体   English

在 C++ 中打印没有演员表的枚举可以吗?

[英]Is printing an enum without a cast okay in C++?

#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));
}

Godbolt link螺栓链接

In the above example, gcc will emit the following diagnostic:在上面的示例中,gcc 将发出以下诊断信息:

<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.无论编译器版本或启用的警告如何,我似乎都无法让 clang 发出相同的诊断信息。 Since this is a warnning and not an error, I assume both are standards compliant.由于这是一个警告而不是错误,我假设两者都符合标准。 Why does gcc complain when clang won't?为什么 clang 不会抱怨时 gcc 会抱怨? Is gcc being overly cautious here, or is there actually something worth warning about? gcc 是否在这里过于谨慎,或者实际上有什么值得警告的?

From cppreference :cppreference

... - arguments specifying data to print. ... - arguments 指定要打印的数据。 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.如果默认转换后的任何参数不是相应转换说明符所期望的类型,或者如果 arguments 比格式所需的少,则行为未定义。 If there are more arguments than required by format, the extraneous arguments are evaluated and ignored如果 arguments 比格式要求的多,则评估并忽略无关的 arguments

Is gcc being overly cautious here, or is there actually something worth warning about? gcc 是否在这里过于谨慎,或者实际上有什么值得警告的?

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?为什么 clang 不会抱怨时 gcc 会抱怨?

When your code has undefined behavior then compilers are not required to issue any diagnostics.当您的代码具有未定义的行为时,编译器不需要发出任何诊断。 GCC is just being nice to you here. GCC 在这里对你很好。

If you are forced to use a type-unsafe API you can always wrap it into something type-safe:如果您被迫使用类型不安全的 API,您始终可以将其包装成类型安全的内容:

void Log(const TEST_ENUM& x) {
    the_actual_logging_api( "%u", static_cast<std:underlying_type<TEST_ENUM>>(x));   
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM