Default_Component_Value with subtype?

ARM 3.6 Array Types specifies:

“Default_Component_Value shall be specified only on a full_type_declaration."

Thus, default initial values can only be given for types and not for subtypes.

Is there any raison?

This prevents to specify a user specific default value on an extern library type which can’t be changed.

This prevents also to specify different default values for several subtypes.

The discussion the ARG had on it makes it sound like there was some sort of standard rule of thumb they followed in that decision, but I haven’t looked through it long enough to see if I can find out why that rule of thumb existed

REF: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai05s/ai05-0228-1.txt?rev=Top1.13

You can do

type T is new P.T with Default_Component_Value => Skidoo;

You then have to convert your T values to P.T when calling operations of P.T.

That is true unless the operation you are calling is a primitive operation of P.T, because the primitive operations of P.T will be inherited by the local T type, but with the local T as the parameter/result type.

Actually, the AI explains its reasoning:

We considered making these subtype aspects rather than type aspects. That would
allow giving different default values to different subtypes. However, given the
existence of many ways to create anonymous subtypes it would be very hard to
guarantee that all values of a type are initialized. Without that guarantee,
these aspects lose a lot of their purpose.

More generally, subtypes are somewhat “soft” in Ada, and particularly for scalar types, exactly which subtype is relevant in a given context can be somewhat unclear. As suggested, a derived type gives you much more control, and the type of a scalar object is never in doubt.

Be that as it may, the aspect could probably be made to work with subtypes, but it would definitely add complexity to the typical Ada implementation.

1 Like

Yes, though I want to avoid that.

The use case is: my subtype restricts the component values of an array with Dynamic_Predicate but I got errors when I create an object of the subtype (without initial value):

subtype T is P.T -- array
   with Dynamic_Predicate => (for all Item of T => Item in R);
...
O : T (1..10); -- ADA.ASSERTIONS.ASSERTION_ERROR

Default_Component_Value would avoid giving initial value at each object creation, especially since the compiler doesn’t warn me if I forget.

It is surprising that I can give a Dynamic_Predicate aspect to a subtype but not Default_Component_Value!

Good point. But predicates don’t in general work very well if you have to put them on the “first” subtype (aka the type as a whole).

In fact, this combination was anticipated, but it seems that whatever compiler you are using didn’t follow the rules stated in RM 3.2.4(31/5), which indicate a predicate is only checked on a default-initialized object if in fact the object has some explicitly specified default initialization:

For an object created by an object_declaration with no explicit initialization expression, or by an uninitialized allocator, if the types of any parts have specified Default_Value or Default_Component_Value aspects, or any subcomponents have default_expressions, a check is performed that the value of the created object satisfies the predicates of the nominal subtype.

So you might want to file a bug report for this, if you have a small reproducer for this problem.

Yes, a derived type derives the primitive operations of its parent type, but those derived operations are not operations of the parent type. I thought it would be clear that the “operations of P.T” would be non-primitive operations, but apparently not.