这是indexloc提供的服务,不要输入任何密码
Skip to content

Clarification for "InitStruct" functions #3766

@dcz-self

Description

@dcz-self

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    apiRelated to the libjxl APIquestionFurther information is requestedunrelated to 1.0Things that need not be done before the 1.0 version milestone

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions