Skip to content

Conversation

@cary-ilm
Copy link
Member

@cary-ilm cary-ilm commented Nov 24, 2025

When OPENEXR_CORE_USE_NAMESPACE=ON, the .c and .h files in OpenEXRCore are built with C++ rather than C, with all symbols in the OPENEXR_IMF_INTERNAL_NAMESPACE namespace just like the OpenEXR library.

This makes is possible to trade the benefits of the C implementation for the benefits of C++ and the namespacing of all symbols.

All code in the OpenEXRCore .c and .h files is now bracketed inside OPENEXR_CORE_NAMESPACE_ENTER and OPENEXR_CORE_NAMESPACE_EXIT, which add namespace directives (e.g. namepace Imf_3_4 {). These degenerate to empty when compiling with C, which is still the default.

There are also macros OPENEXR_CORE_EXTERN_C_ENTER/OPENEXR_CORE_EXTERN_C_EXIT for the OpenEXRCore code that needs extern "C" {, which reverts the the C++ OpenEXR namespace in C++.

This also adds missing C++ casts to OpenEXRCore, required by C++ even though the are not necessary in C.

Also, the _priv_exr_part_t struct now has a custom constructor and assignment operator because its chunk_table field is a atomic_uintptr_t, which has those methods deleted.

This also includes some necessary changes to the vendored libdeflate code to compile in C++.

When building OpenEXR with the default configuration, this produces the same object code as before. The namespaced symbols are only generated when configured to do so. As as test, I ran nm on the shared library and got the same symbols as before.

Website preview: https://openexr--2205.org.readthedocs.build/en/2205/

When `OPENEXR_CORE_USE_NAMESPACE=ON`, the .c and .h files in
OpenEXRCore are built with C++ rather than C, with all symbols in the
`OPENEXR_IMF_INTERNAL_NAMESPACE` namespace just like the OpenEXR
library.

This makes is possible to trade the benefits of the C implementation
for the benefits of C++ and the namespacing of all symbols.

All code in the OpenEXRCore .c and .h files is now bracketed inside
`OPENEXR_CORE_NAMESPACE_ENTER` and `OPENEXR_CORE_NAMESPACE_EXIT`,
which add namespace directives (e.g. `namepace Imf_3_4 {`). These
degenerate to empty when compiling with C, which is still the default.

There are also macros
`OPENEXR_CORE_EXTERN_C_ENTER/OPENEXR_CORE_EXTERN_C_EXIT` for the
OpenEXRCore code that needs `extern "C" {`, which reverts the the C++
OpenEXR namespace in C++.

This also adds missing C++ casts to OpenEXRCore, required by C++ even
though the are not necessary in C.

Also, the `_priv_exr_part_t` struct now has a custom constructor and
assignment operator because its `chunk_table` field is a
`atomic_uintptr_t`, which has those methods deleted.

This also includes some necessary changes to the vendored `libdeflate`
code to compile in C++.

When building OpenEXR with the default configuration, this produces
the same object code as before.  The namespaced symbols are only
generated when configured to do so. As as test, I ran `nm` on the
shared library and got the same symbols as before.

Signed-off-by: Cary Phillips <[email protected]>
@cary-ilm
Copy link
Member Author

By the way, I'm not crazy about the name of this build option, OPENEXR_CORE_USE_NAMESPACE=ON, I'd welcome a suggestion for something better.

@cary-ilm cary-ilm requested a review from Copilot November 25, 2025 19:57
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces the OPENEXR_CORE_USE_NAMESPACE build option, which allows OpenEXRCore to be compiled with C++ (instead of the default C) with all symbols placed in the same namespace as the OpenEXR library. This enables linking multiple versions of OpenEXR in the same program without symbol conflicts. The implementation adds namespace macros throughout the OpenEXRCore codebase and includes necessary C++ casts required for compilation.

Key changes:

  • New CMake option OPENEXR_CORE_USE_NAMESPACE that switches OpenEXRCore from C to C++
  • Namespace macros (OPENEXR_CORE_NAMESPACE_ENTER/EXIT and OPENEXR_CORE_EXTERN_C_ENTER/EXIT) added throughout OpenEXRCore
  • C++ explicit casts added where C's implicit conversions are not allowed

Reviewed changes

Copilot reviewed 99 out of 101 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
website/install.rst Documents the new OPENEXR_CORE_USE_NAMESPACE option and linking multiple OpenEXR versions
cmake/OpenEXRConfig.h.in Defines the namespace macros that conditionally add C++ namespaces
src/lib/OpenEXRCore/CMakeLists.txt Adds logic to compile .c files as C++ when OPENEXR_CORE_USE_NAMESPACE is enabled
src/lib/OpenEXRCore/*.c Adds namespace macros and C++ casts to all OpenEXRCore implementation files
src/lib/OpenEXRCore/*.h Replaces extern "C" blocks with namespace macros in header files
src/test/OpenEXRCoreTest/*.cpp Updates test files to use OPENEXR_IMF_NAMESPACE consistently
external/deflate/lib/*.c Adds C++ casts to vendored libdeflate code for C++ compatibility
.github/workflows/*.yml Adds CI workflow configuration to test the new option

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

return EXR_UNLOCK_WRITE_AND_RETURN (ctxt->print_error ( \
ctxt, EXR_ERR_INVALID_ARGUMENT, "NULL output for '%s'", name)); \
*out = attr->entry; \
*out = EXR_CAST_TO_TYPE_OF(*out) attr->entry; \
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The macro EXR_CAST_TO_TYPE_OF uses decltype for MSVC C++ and __typeof__ for GCC/Clang. This adds a space after the cast in C mode which changes the semantics slightly. The empty definition for C mode should be verified to not cause issues with operator precedence in complex expressions.

Copilot uses AI. Check for mistakes.
cary-ilm and others added 3 commits November 25, 2025 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant