Bart Vandewoestyne
Bart Vandewoestyne

Reputation: 553

Compiler error when using Info-ZIP 3.0 source code

In our legacy C++ code base, we are using Info-ZIP 3.0 source code (written in C) available from https://sourceforge.net/projects/infozip/files/Zip%203.x%20%28latest%29/3.0/ to create ZIP-files. Switching to another framework for ZIP-file creation is currently not an option due to time constraints. To use this code, we do something like

extern "C" {
  #include "api.h"
}
...
extern "C" int EXPENTRY ZpArchive(ZCL C, LPZPOPT Opts);

This has worked well with VS2015, but it no longer compiles when switching to VS2019. The problem is that Info-ZIP's api.h includes Info-ZIP's zip.h, which has the following define:

  #define CR     13

later on, api.h also conditionally includes windows.h:

#if defined(WINDLL) || defined(API)
#include <windows.h>
...
#endif /* WINDLL? || API? */

which eventually also includes winnt.h which has the following typedef:

typedef struct _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY {
    DWORD BeginAddress;
    union {
        DWORD UnwindData;
        struct {
            DWORD Flag : 2;
            DWORD FunctionLength : 11;
            DWORD RegF : 3;
            DWORD RegI : 4;
            DWORD H : 1;
            DWORD CR : 2;
            DWORD FrameSize : 9;
        } DUMMYSTRUCTNAME;
    } DUMMYUNIONNAME;
} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY, * PIMAGE_ARM64_RUNTIME_FUNCTION_ENTRY;

Note that the CR member in the inner struct from this typedef conflicts with the previously defined CR macro, and this gives a compiler error.

What would be a clean way to solve this, preferably without changing Info-ZIP's source code too much (or even nothing at all)?

Upvotes: 1

Views: 305

Answers (2)

Armali
Armali

Reputation: 19395

I am wondering if there exists a solution for which I don't need to change Info-ZIP's code.

Provided that windows.h has an include guard, a solution could be to include it first:

#include <windows.h>
extern "C"
{
  #include "api.h"
}

This way, the struct definition is parsed before the #define CR gets in the way. Of course, this only works if the CR element of the struct is not used later in the compilation unit.

Upvotes: 0

Bart Vandewoestyne
Bart Vandewoestyne

Reputation: 553

I finally decided to solve the problem by renaming the CR macro to INFOZIP_CR. It turned out I had to do that only in four places, so the impact on the Info-ZIP source code is rather minimal. Thanks for all the comments/suggestions.

Upvotes: 1

Related Questions