Opened 5 days ago
#294 new enhancement
Polymorphic nested aggregates may over-generalize the inner type
Reported by: | mlbrooks | Owned by: | |
---|---|---|---|
Priority: | minor | Component: | cfa-cc |
Version: | 1.0 | Keywords: | |
Cc: |
Description
Compare these two applications of nested aggregates with polymorphism, both for the union-within-struct arrangement.
// style 1 forall( T, U ) struct variant { int tag; union { T first; U second; }; };
// style 2 forall( T ) struct _Ostream_Manip { T val; int wd, pc; char base; union { unsigned char all; _Ostream_Flags flags; }; };
In style 1, the polymorphic part is within the inner aggregate, while in style 2, it is properly within the outer. So, the style-2 inner aggregate need not be lowered as a generic: its size and layout do not depend on the size or alignment of T. With style 1, the opposite is true.
Present state treats style 1 as the general case: sometimes the generic parameters are used by the inner aggregate, so treat an inner aggregate as being as generic as the outer.
This ticket parks the suggestion to have more cases in the above rule, and make the inner aggregate only as generic as it needs to be. Doing so could reduce unnecessary runtime cost from handling the inner part via RTTI.
A consequence of present state is that style 2 gets an unused variable warning: _sizeof_T is not used in function _layoutofOstream_ManipanonymousN. (Note the "anonymous" suffix means it's the layoutof function for the inner aggregate, the anonymous union). This warning is meaningful (though could be cleaned up for non-CFA gurus) in the case of
forall( T ) // same for T * or explicit sized(T) struct X { T * x; };
where it signifies, "You don't need to be forall-T or forall-T* here; you can be forall-T&," a helpful catch. Therefore, one is reluctant to silence the warning outright, by stamping attribute-unused on all sizeof input parameters to layoutof functions.