9

C++11 adds enum classes, which are stronger-typed enums - values of enum classes will not be implicitly converted to values of other enum classes or integers, and forward-declarations are permitted by virtue of an explicit size specifier.

Is it possible to pass values of such enumerations to varargs functions and remain within standards-defined behavior? Within implementation-defined behavior?

Wolf
  • 9,679
  • 7
  • 62
  • 108

3 Answers3

9

Yes, you can. 5.2.2/7 explicitly allows arguments of any enumeration type. Unscoped enum values are integer promoted, but scoped enums (the enum class ones) are not.

Of course you still have to be careful in the implementation of the function.

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64
  • 1
    +1 for the 5.2.2/7 reference - I'm pretty sure if `enum class` was exempt from that there would be a note there. – Flexo Oct 16 '11 at 19:54
  • 1
    I wonder whether it is UB to use the underlying type with `va_arg`, when the argument fetched was a scoped enumeration value? It appears it is. – Johannes Schaub - litb Oct 16 '11 at 20:02
  • @Johannes : If that causes UB, then doesn't that defeat the purpose of specifying the underlying type in the first place (identical value representation)? – ildjarn Oct 16 '11 at 20:34
  • @Johannes 18.10/3 says it's ok if the parameter and argument types are compatible - but unfortunately "compatible types" seems to be a C not a C++ notion. I'm sure it would work - but I strongly suspect it is technically UB. – Alan Stokes Oct 16 '11 at 21:14
1

I think the answer is that it can be safe:

VA_ARGS requires arguments to be POD, that hasn't changed as far as I'm aware.

I can't see any reason why:

enum class foo { bar=1 };

Wouldn't meet the requirements for POD-ness though.

Flexo
  • 87,323
  • 22
  • 191
  • 272
0

As you throw away some type information when using varargs (that's why it's strongly discouraged for non POD types) you will just receive the underlying type at the other end of your varargs using function. The default is int but you can change that (e.g. enum class MyEnum : char { ... };)

Corrected: varargs does indeed not throw away all type information and if you use POD data type you should be quite safe.

znkr
  • 1,746
  • 11
  • 14