http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58709
Paul Pluzhnikov <ppluzhnikov at google dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED CC| |jdennett at google dot com Resolution|--- |INVALID --- Comment #4 from Paul Pluzhnikov <ppluzhnikov at google dot com> --- James Dennett says: I believe that the code is incorrect, and the warning is valid. For calls via varargs: . If the argument has integral or enumeration type that is subject to the integral promotions (4.5), or a floating point type that is subject to the floating point promotion (4.6), the value of the argument is converted to the promoted type before the call. These promotions are referred to as the default argument promotions. And scoped enumerations are not "subject to the integral promotions"; only unscoped enums are: . The value of an enumerator or an object of an unscoped enumeration type is converted to an integer by integral promotion (4.5). So it (the scoped enumeration value) is not passed as an int, and using va_arg to pull it out as an int is undefined behavior. Well, the full story is even worse; va_arg is defined by the C standard (not the C++ standard) and in particular is defined in terms of "compatible" types. C says that its enums are compatible with some underlying (but unspecified) integral type, but naturally C has nothing to say about scoped enumerations. It would be reasonable for C++ to specify that varargs calls apply the default argument promotions to scoped enumerations also, but that's not how C++ is written today. The intent of scoped enums is that they never implicitly act like integers, from which perspective it's good to require people to convert to the underlying type if they must use varargs.