-
Notifications
You must be signed in to change notification settings - Fork 317
Description
Is your feature request related to a problem? Please describe.
Procedures like JxlEncoderInitBasicInfo have a documentation saying "For forwards-compatibility, this function has to be called before values are assigned to the struct fields.", but in my understanding, it will not do anything for compatibility in many cases.
Describe the solution you'd like
A clear and concise description of what kind of compatibility will be preserved (source? ABI?) and under what circumstances.
Describe alternatives you've considered
I could ignore my understanding, just do what the docs say, and have complicated code to do something which might actually need a really simple solution.
Additional context
I'm trying to extend the Rust bindings for my use case. The bindings don't use the struct definitions from .h headers, but rather use a manually updated copy. This means there is no source forward-compatibility, because every time an extra field is added, that change must be reflected under penalty of crashes.
But the way I see it, the init calls don't provide any binary forward-compatibility no matter what the source language is.
I assume that the need for compatibility arises when the struct gains new fields, and those need to be initialized. So let's consider a typical sequence:
// struct JxlInfo {
// uint32_t a_field;
// };
struct JxlInfo *info = malloc(sizeof(info)); // allocs 4 bytes
jxlInitInfo(info);
info->a_field = 1;
This works fine in version 0.1. Now we bump to the next version and add a field:
struct JxlInfo {
uint32_t a_field;
uint32_t disabled; // added in 0.2
};
void jxlInitInfo(*info) {
info->a_field = 0;
info->disabled = false;
}
Running the same code without recompiling:
struct JxlInfo *info = malloc(sizeof(info)); // not recompiled; STILL allocs 4 bytes
jxlInitInfo(info); // tries to access info->disabled at offset 4, past the end of the allocated area
In this case, the Init procedure just crashes the client application because it doesn't change the allocation size. It can't work any other way as long as it doesn't allocate the data.
This behaviour is very confusing to me and doesn't resemble forward compatibility at all, and eliminates the ability to use dynamically linked libraries, so I'm probably focusing on a different use case than intended.
Could you clarify the docs to make it obvious what the init procedures are for and how/when to use them?