Add abilitiy to specify the array length type
Submitted by bob..@..131.so
Link to original bug (#791506)
Description
For arrays defined in Vala source, valac will always generate C code using `int' as the type for the length and size fields. I have some (probably controversial) patches, but I just want to describe where I'm coming from with this:
I assume a signed type was chosen as a good default for the length field so invalid values like -1 can have an out-of-band representation, but I would have thought ssize_t would be a better choice. It might have to remain the default for the sake of API and ABI compatibility, which is perfectly acceptable if the user has means to choose a different type.
On the other hand, using `int' for size seems like a really terrible idea:
- Being a piece of book-keeping handled statically by the compiler, there shouldn't be any use for invalid values.
- It introduces a hard-limit for any array operations Vala does, at a measly 2^15 elements in the worst standard-compliant case (of course, the common x86 environments bump this up to 2^31, but we really ought not to be relying on this sort of implementation-defined behaviour).
- This implementation detail is completely hidden from the user, rendering them unable to correct this behaviour without ugly sed scripts and the like.
I would argue that any type other than size_t for this field creates fundamentally broken code, but there might be a place for it despite whatever I might claim ;) In this case, I would think it ought to be a user-configurable thing a la CCode.array_length_type.
So, with that out of the way, the basic plan my patches implement is this:
- Update Vala.ArrayType to honor CCode.array_length_type and introducing a method for this type to be queried by codegen.
- Update the relevant codegen modules to use an ArrayType's configured length field type and unconditionally use size_t for array size fields.
- Use an ArrayType's configured length field type as the type for indexes in foreach statements operating on arrays.
A couple of things might be worth looking at that I haven't addressed:
-
Altering the .move() and .resize() method signatures to respect the configured field types. It seems as though valac generates one of these functions per source file that get shared amongst all the calls to these methods for various different array types. I wasn't sure generating several instances of the same function with different signatures was a good thing to do, so I just left this alone.
-
Trying to correctly infer the type of the index in a statement like `for (var i = 0; i < array.length; i++)'. I'm not sure how sophisticated valac's (or any compiler's) type inferencing is, but this seems like something that would become a jungle of corner-cases. Can this be done?
-
I haven't touched the DBus codegen module since I wasn't sure if there were DBus-specific knock-on effects.