2021.01.01 19:31 "[Tiff] Enabling and requiring C99 language support", by Roger Leigh

2021.01.02 21:05 "Re: [Tiff] Enabling and requiring C99 language support", by Roger Leigh

There is ongoing discussion of this on:

For anyone who isn’t following the discussion of the above, this is to bring it to a wider audience.

The main question to address is: how far can we go in switching over to C99?

The main issue with !51 is this part of the public headers:

https://gitlab.com/libtiff/libtiff/-/blob/master/libtiff/tiff.h#L66

Here, we define the types int8, int16, int32, int64 and uint8, uint16, uint32, uint64. These don’t have a “tiff_" prefix and so have the potential to clash with other libraries which also define these types nonportably. Since this is now reported to happen in the real world, we do need to consider how to correct the problem.

Unfortunately, given that user code may be using these types, any change to the name would be a potential cause of breakage. Two options are to add the “tiff_" prefix to the types. Or if we require C99, to simply use the C99 int8_t … uint64_t types directly. Neither would avoid the need for a major version bump.

To provide some more context for discussion. Over the last couple of days, I’ve been working on a prototype for this conversion so we can see exactly what the consequences would be. For the bullet points above:

The first branch (tiff-integer-typedefs) replaces the types “int8”.. “uint64” with new typedefs “tiff_int8_t”.. “tiff_uint64_t”. The bulk of the changes here are the renaming of types across the entire codebase and the documentation. Note that the old type names are retained (but unused) to avoid a compatibility break.

The second adds an option “legacy-types” (CMake) or “enable-legacy-types” (Autoconf) which sets a TIFF_LEGACY_TYPES macro. This will only enable the “int8”.. “uint64” types if the option is used explicitly (though the default could be changed to enable by default until we want to turn off). Because the previous change switched all the interfaces over to using the new “tiff_int8_t”.. “tiff_uint64_t” types, the only reason to enable this is to allow third-party codebases to use the legacy types. They can also compile with -DTIFF_LEGACY_TYPES to override the compile-time default should they choose to.

Up until this point, C99 is not required.

The last branch is the one which enables and requires C99 support unconditionally, and switches the “tiff_int8_t”.. “tiff_uint64_t” types over to using stdint.h and inttypes.h with the standard “int8_t”.. “uint64_t” types throughout the whole codebase and the documentation.

The last branch also includes a few small cleanups which could be split out on their own.

In order to satisfy the problem with clashing types, I’d personally like to recommend using the tiff-integer-typedefs and legacy-typedef-option branches. This will solve the problem, move the libtiff interfaces over to using non-clashing portable typenames, and will still permit use with older compilers, while making use of C99 types on systems which support them. I think that’s a good compromise to make for where we are today. If anyone wants to test these two branches out, it would be interesting to see how they behave on older systems. They all pass the CI on Linux and Windows; but we don’t actually have any CI support for obsolete systems (with good reason).

The C99 branch one could be applied if there is consensus to go that far. Personally, I’d be all for doing that. But if we want to stop one step short of this, we still have most of the benefit (at least, from the point of view of the standard integer types; there are clearly many other C99 features which the project could benefit from which would improve the code quality and robustness).

Kind regards,

Roger