Comments (5)
Is there a reason to treat them differently from an unscoped enum
? Are there compilers that do anything different?
from cxx-abi.
Unscoped enum
s are passed as their promoted type, and can be retrieved thusly with va_arg
. Scoped enum
s don't promote, so we would need to decide how to pass them (as the underlying type, or as the promoted underlying type?) and what types can validly be used with va_arg
to retrieve them (the original enum type, its underlying type, and/or its promoted underlying type).
Does anyone still use have a macro implementation of va_arg
that can't easily carry custom logic to deal with this case?
from cxx-abi.
You're right that you'd have to pass the scoped enum type to va_arg
to read the argument, but as far as I can tell that's always been valid. And a macro implementation of va_arg
would presumably just read the value out of the va_list
as a scoped_enum *
and then bump up to the next slot, exactly like it would any other type.
I guess what I'm saying is that I'm surprised that people think that this hasn't been supported behavior for the last 10+ years. Was there a bug report or something?
from cxx-abi.
Well, consider enum class X : char {};
. Presumably that would be passed as an int
, because the psABI doesn't specify how to pass anything smaller. But now consider a simple va_arg
macro:
#define va_arg(list, type) (*(type*)(list -= sizeof(type)))
That macro fails for X
, because it will bump list
an insufficient distance. GCC and Clang both support this anyway, but GCC at least does not support the corresponding case where you use char
instead of X
(Clang allows even that and makes it work).
If on the other hand we had enum X : char {};
instead of enum class X : char {};
then the rules are clear that X
is promoted to int
when passed through ...
, and va_arg(list, X)
has undefined behavior.
So we have at least a choice between treating scoped and unscoped enums the same (and requiring the promoted underlying type to be used in the va_arg
), or treating them differently (and allowing -- and perhaps expecting -- the original type to be used in the va_arg
for the scoped case). And the latter is the status quo in GCC and Clang.
from cxx-abi.
Well, psABIs definitely specify how to pass e.g. a one-byte struct, and if that struct is trivially copyable it's allowed with varargs, so it's not strictly true that psABIs don't specify how to pass anything smaller, even if it's not obvious that that would be the right rule to use for scoped enums.
That definition of va_arg
doesn't work for similar reasons. It also doesn't correctly handle the partitioning of the argument area into aligned slots in general, although for a target with sizeof(int) == sizeof(void*)
it might incidentally work out for at least standard types. It also walks the argument area in the wrong direction from the normal convention, although that's a fixable mistake. (It's actually quite awkward to fix: I think you'd have to do something awful like * (const T *) (*(const char (**)[(sizeof(T) + slot_size - 1) / slot_size * slot_size]) list)++)
), and even that relies on types never being overaligned for a slot, and of course it has strict-aliasing problems.)
Anyway, I agree that we need to specify some sort of default rule for psABIs that are written purely in terms of C/Fortran/whatever. Note that that means specifying a rule for these types in general, not just a rule for variadic arguments. Since we have to lower them to concepts known to be handled by the psABI, I think we have two options: handle them as the underlying type or handle them as a struct containing a single field of the underlying type. The former seems like the more obvious choice.
I would suggest:
Let
E
be a scoped enumeration type with underlying typeU
. Unless the psABI provides specific rules forE
, they are as follows:
- An object of type
E
has the same representation and characteristics as an object of typeU
.- An argument of type
E
is passed as if it were converted to typeU
and as if the corresponding parameter (if any) was of typeU
.- A return value of type
E
is returned as if it were converted to typeU
and returned from a function with return typeU
.If an argument of type
U
would be subject to the default argument promotions, the implementation must perform the appropriate promotion to an argument of typeE
even though the promotions do not formally apply. Note that programs are required to passE
tova_arg
, notU
, which may cause trouble for simple definitions ofva_arg
.
I don't think we've actually specified this lowering as this level of detail for any of the existing C++-specific types. For example, we give layout rules for member pointers, but not CC rules; and I'm not sure we ever specify that references have the same representation as pointers.
from cxx-abi.
Related Issues (20)
- "Deducing this" mangling HOT 14
- Should std::rethrow_exception be covered by the EH ABI? HOT 2
- Emergency EH buffer is overspecified HOT 6
- Where is the most recent ABI document? HOT 1
- Add `[[trivial_abi]]` attribute
- Lambda POD for the purposes of layout? HOT 2
- Mangling the name of an externally visible lambda in a static data member of a class HOT 1
- Proposal: Include an optional specification for mangling names that reference anonymous symbols HOT 4
- Is it possible to form a pointer-to-data-member with offset -1 using explicit derived-to-base conversions without UB? HOT 3
- unnecessary `E`s after <expression> and mangling collisions between <expression> and <number> HOT 1
- need mangling for lambdas appearing in unevaluated operands within a class body HOT 3
- What does "forbidding the use of function templates" mean? HOT 2
- [C++20] [Modules] Do we need the concept of `key function` for class defined in module purview? HOT 25
- Missing HTML encoding in 2.3.1 Data Member Pointers HOT 2
- Proposal: document or somehow notice __cxa_init_primary_exception HOT 3
- Mangling for C++ pack indexing HOT 1
- Function and function pointer types with vendor calling conventions HOT 2
- Ambiguity in mangling grammar around type qualifiers HOT 8
- Question about section 2.9.4 HOT 4
- Questions About Non-POD Types Data Layout HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cxx-abi.