Skip to content

MSVC build fails on CMake re-configure due to cached C99 complex type size (Cache pollution) #6051

@xorespesp

Description

@xorespesp

Describe the bug:

When building HDF5 v2.0.0 on Windows with MSVC, the first clean configuration works correctly. However, if CMakeLists.txt is modified or a re-configuration is triggered within the same build directory(e.g., touching CMakeLists.txt in IDE after a successful first build), the build fails with syntax errors in H5private.h regarding H5_float_complex.

...\src\H5private.h(592): error C2061: syntax error: identifier 'H5_float_complex'

Environment:

  • HDF5 Version: 2.0.0
  • OS: Windows 11 24H2 x64
  • Compiler: Visual Studio 2022 (MSVC) 17.14.21
  • CMake version: 4.1.1 (generator: Ninja)

Root Cause Analysis:

This happens because H5_HAVE_C99_COMPLEX_NUMBERS is incorrectly set to 1 during CMake re-configuration.
In config/ConfigureChecks.cmake, there is a "safety block" for MSVC to fallback to _Fcomplex and unset the C99 complex flag:

  ...
  if (MSVC AND NOT ${HDF_PREFIX}_SIZEOF_FLOAT_COMPLEX AND NOT ${HDF_PREFIX}_SIZEOF_DOUBLE_COMPLEX
      AND NOT ${HDF_PREFIX}_SIZEOF_LONG_DOUBLE_COMPLEX)
    # If using MSVC, the _Complex types (if available) are _Fcomplex, _Dcomplex and _Lcomplex.
    # The standard types are checked for first in case MSVC uses them in the future or in case
    # the compiler used is simulating MSVC and uses the standard types.
    cmake_push_check_state ()
    list (APPEND CMAKE_EXTRA_INCLUDE_FILES complex.h)
    HDF_CHECK_TYPE_SIZE ("_Fcomplex" ${HDF_PREFIX}_SIZEOF__FCOMPLEX)
    HDF_CHECK_TYPE_SIZE ("_Dcomplex" ${HDF_PREFIX}_SIZEOF__DCOMPLEX)
    HDF_CHECK_TYPE_SIZE ("_Lcomplex" ${HDF_PREFIX}_SIZEOF__LCOMPLEX)
    cmake_pop_check_state ()
    if (${HDF_PREFIX}_SIZEOF__FCOMPLEX AND ${HDF_PREFIX}_SIZEOF__DCOMPLEX AND
        ${HDF_PREFIX}_SIZEOF__FCOMPLEX)
      set (${HDF_PREFIX}_SIZEOF_FLOAT_COMPLEX ${${HDF_PREFIX}_SIZEOF__FCOMPLEX}
           CACHE INTERNAL "SizeOf for float _Complex" FORCE)
      set (${HDF_PREFIX}_SIZEOF_DOUBLE_COMPLEX ${${HDF_PREFIX}_SIZEOF__DCOMPLEX}
           CACHE INTERNAL "SizeOf for double _Complex" FORCE)
      set (${HDF_PREFIX}_SIZEOF_LONG_DOUBLE_COMPLEX ${${HDF_PREFIX}_SIZEOF__LCOMPLEX}
           CACHE INTERNAL "SizeOf for long double _Complex" FORCE)

      unset (H5_HAVE_C99_COMPLEX_NUMBERS)
    endif ()
  endif ()
  ...

This safety block works for the first clean build, but does not work when CMake is re-configured later.
Here is the failure scenario:

  1. On the first run(clean build), ConfigureChecks.cmake correctly identifies that MSVC assumes standard float _Complex is not supported, finds _Fcomplex instead, and forces H5_SIZEOF_FLOAT_COMPLEX into the cache.
  2. On the second run, check_type_size("float _Complex") finds the cached variable H5_SIZEOF_FLOAT_COMPLEX and assumes the standard type is supported.
  3. Consequently, the "safety block" is skipped.
  4. H5_HAVE_C99_COMPLEX_NUMBERS remains ON, causing syntax errors in H5private.h because MSVC does not support the _Complex keyword syntax despite having the header and size info.

Proposed fix:

See #6052

Metadata

Metadata

Assignees

Type

Projects

Status

In progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions