ODR violation in JUCE zlib

Compiling on GCC with LTO enabled. I get these scary warnings about ODR violations:

/path/to/JUCE/modules/juce_core/zip/zlib/deflate.h:96:16: warning: type ‘struct internal_state’ violates the C++ One Definition Rule [-Wodr]
 typedef struct internal_state {
                ^
/path/to/JUCE/modules/juce_graphics/image_formats/../../juce_core/zip/zlib/zlib.h:1347:12: note: a different type is defined in another translation unit
     struct internal_state {int dummy;}; /* hack for buggy compilers */
            ^
/path/to/JUCE/modules/juce_core/zip/zlib/deflate.h:97:15: note: the first difference of corresponding definitions is field ‘strm’
     z_streamp strm;      /* pointer back to this zlib stream */
               ^
/path/to/JUCE/modules/juce_graphics/image_formats/../../juce_core/zip/zlib/zlib.h:1347:32: note: a field with different name is defined in another translation unit
     struct internal_state {int dummy;}; /* hack for buggy compilers */
                                ^
/path/to/JUCE/modules/juce_core/zip/zlib/zlib.h:83:16: warning: type ‘struct z_stream_s’ violates the C++ One Definition Rule [-Wodr]
 typedef struct z_stream_s {
                ^
/path/to/JUCE/modules/juce_graphics/image_formats/../../juce_core/zip/zlib/zlib.h:83:16: note: a different type is defined in another translation unit
 typedef struct z_stream_s {
                ^
/path/to/JUCE/modules/juce_core/zip/zlib/zlib.h:93:32: note: the first difference of corresponding definitions is field ‘state’
     struct internal_state FAR *state; /* not visible by applications */
                                ^
/path/to/JUCE/modules/juce_graphics/image_formats/../../juce_core/zip/zlib/zlib.h:93:32: note: a field of same name but different type is defined in another translation unit
     struct internal_state FAR *state; /* not visible by applications */
                                ^
/path/to/JUCE/modules/juce_core/zip/zlib/deflate.h:96:16: note: type ‘struct internal_state’ itself violates the C++ One Definition Rule
 typedef struct internal_state {
                ^
/path/to/JUCE/modules/juce_graphics/image_formats/../../juce_core/zip/zlib/zlib.h:1347:12: note: the incompatible type is defined here
     struct internal_state {int dummy;}; /* hack for buggy compilers */
            ^

Thanks for reporting! Does defining NO_DUMMY_DECL make the warnings go away for you?

If I try to do that, I get the following error

In file included from /path/to/JUCE/modules/juce_core/juce_core.cpp:178:0,
                 from /my/project/cmake-build-release/JuceCommonLibs/JuceLibraryCode/include_juce_core.cpp:9:
/path/to/JUCE/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp:68:0: error: "NO_DUMMY_DECL" redefined [-Werror]
   #define NO_DUMMY_DECL

I tried to repro this over the weekend, building UnitTestRunner and DemoRunner. I used gcc 9.3 and enabled the LTO option in the Projucer. I didn’t get any warnings like the ones you pasted.

Could you give any more details about the setup you’re using? If possible, pasting the compiler invocation that causes the error would be really useful, so that I can see all the flags that are being used.

I have the same problem, but at the same time an internal linker error on Debian 9 with gcc 8.5.0. I managed to separate the warning above however from the linker error on an Azure pipeline agent with gcc 7.5.0, so I think the compiler warning and the linker crash are unrelated.

Both Linux systems however show the warning timur mentions, and adding the -DNO_DUMMY_DECL does make the compiler warnings go away (with a new warning about redefining NO_DUMMY_DECL, which timur treats as an error), but not the subsequent linker warnings about ODR violations.

[ 83%] Linking CXX shared module pytschirp.cpython-36m-x86_64-linux-gnu.so
/home/vsts/work/1/s/third_party/JUCE/modules/juce_core/zip/zlib/deflate.h:96:16: warning: type ‘struct internal_state’ violates the C++ One Definition Rule [-Wodr]
 typedef struct internal_state {
		^
/home/vsts/work/1/s/third_party/JUCE/modules/juce_graphics/image_formats/../../juce_core/zip/zlib/zlib.h:1347:12: note: a different type is defined in another translation unit
     struct internal_state {int dummy;}; /* hack for buggy compilers */
	    ^
/home/vsts/work/1/s/third_party/JUCE/modules/juce_core/zip/zlib/deflate.h:97:15: note: the first difference of corresponding definitions is field ‘strm’
     z_streamp strm;      /* pointer back to this zlib stream */
	       ^
/home/vsts/work/1/s/third_party/JUCE/modules/juce_graphics/image_formats/../../juce_core/zip/zlib/zlib.h:1347:32: note: a field with different name is defined in another translation unit
     struct internal_state {int dummy;}; /* hack for buggy compilers */
				^
/home/vsts/work/1/s/third_party/JUCE/modules/juce_core/zip/zlib/zlib.h:83:16: warning: type ‘struct z_stream_s’ violates the C++ One Definition Rule [-Wodr]
 typedef struct z_stream_s {
		^
/home/vsts/work/1/s/third_party/JUCE/modules/juce_graphics/image_formats/../../juce_core/zip/zlib/zlib.h:83:16: note: a different type is defined in another translation unit
 typedef struct z_stream_s {
		^
/home/vsts/work/1/s/third_party/JUCE/modules/juce_core/zip/zlib/zlib.h:93:32: note: the first difference of corresponding definitions is field ‘state’
     struct internal_state FAR *state; /* not visible by applications */
				^
/home/vsts/work/1/s/third_party/JUCE/modules/juce_graphics/image_formats/../../juce_core/zip/zlib/zlib.h:93:32: note: a field of same name but different type is defined in another translation unit
     struct internal_state FAR *state; /* not visible by applications */
				^
/home/vsts/work/1/s/third_party/JUCE/modules/juce_core/zip/zlib/deflate.h:96:16: note: type ‘struct internal_state’ itself violates the C++ One Definition Rule
 typedef struct internal_state {
		^
/home/vsts/work/1/s/third_party/JUCE/modules/juce_graphics/image_formats/../../juce_core/zip/zlib/zlib.h:1347:12: note: the incompatible type is defined here
     struct internal_state {int dummy;}; /* hack for buggy compilers */
	    ^

The setup I am using is highly customized CMake, open source repo https://github.com/christofmuc/KnobKraft-orm branch “mks80”.

Sadly, my virtual test machine is the Debian 9 which has the internal linker error, so the positive result of the Azure build machine doesn’t help me much to tell you if the code works despite the linker warnings.

1 Like

Which branch are you using? I think this issue is resolved on the juce6 branch.

I am on JUCE 5.4.7, but just switched to juce6 as of May 22 and sadly no difference. It does look to me like a compiler problem however, because the linker crashes with an internal linker error on gcc 8.3.0, but the same code compiles with gcc 7.5.0 on another VM.

Just to document this somewhere: We had more problems on Ubuntu 19 with gcc 9.2.1, and the solution is to disable link time optimization (LTO). It seems the pybind11 libraries do their own cmake thing to enable this, and the juce “hack for buggy compilers” triggers buggy compilers into a crash in that situation. When you disable pybind11’s LTO, all works.