Menu

#579 strnlen and posix_memalign not defined with Clang 22 inside Utilities/gdcmext/*.c translation units; missing: _POSIX_C_SOURCE=200809L

3.1
open
nobody
None
5
2026-03-23
2026-03-18
No

Hi, there's no milestone past 3.1, but this was observed with GDCM 3.2.5. I set 3.1 on this ticket because it seemed to be the newest.

When attempting to compile the .c translation units underneath Utilities/gdcmext with Clang 22 I get the following error (NB: this isn't the only affected translation unit!):

Utilities/gdcmext/mec_mr3.c:108:22: error: call to undeclared function 'strnlen'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
  108 |   const size_t len = strnlen(str, buf_len);
      |                      ^
Utilities/gdcmext/mec_mr3.c:108:22: note: did you mean 'strlen'?
/usr/include/string.h:407:15: note: 'strlen' declared here
  407 | extern size_t strlen (const char *__s)
      |               ^
1 error generated.

This makes sense, since the man page for strnlen mentions:

       strnlen():
           Since glibc 2.10:
               _POSIX_C_SOURCE >= 200809L
       strnlen():
           Since glibc 2.10:
               _POSIX_C_SOURCE >= 200809L

So the proper way would be for these handful of translation units to be handed a -D_POSIX_C_SOURCE=200809L prior to including <string.h> by whichever means.

The easiest way I can offer to test this scenario is to invoke the cmake generator step with env CFLAGS="-std=c17" CC=clang CXX=clang++ prepended.

Here's a diff of the changes I made in my vendored version:

diff --git i/Source/MediaStorageAndFileFormat/CMakeLists.txt w/Source/MediaStorageAndFileFormat/CMakeLists.txt
index 51a3ff629..f09d84722 100644
--- i/Source/MediaStorageAndFileFormat/CMakeLists.txt
+++ w/Source/MediaStorageAndFileFormat/CMakeLists.txt
@@ -116,27 +116,35 @@ set(MSFF_SRCS
   )

 # Do the proper thing when building static...if only there was configured
 # headers or def files instead
 if(NOT BUILD_SHARED_LIBS)
   set_source_files_properties(gdcmJPEG2000Codec.cxx
                               PROPERTIES

-                              COMPILE_FLAGS -DOPJ_STATIC
+                              COMPILE_DEFINITIONS OPJ_STATIC
                               )
   set_source_files_properties(gdcmJPEGLSCodec.cxx
                               PROPERTIES
                               COMPILE_DEFINITIONS CHARLS_STATIC
                               )
 else()
   set_source_files_properties(gdcmJPEGLSCodec.cxx
                               PROPERTIES
-                              COMPILE_FLAGS -DCHARLS_DLL
+                              COMPILE_DEFINITIONS CHARLS_DLL
                               )
 endif()

+set_source_files_properties(

+                              ${GDCM_SOURCE_DIR}/Utilities/gdcmext/csa.c
+                              ${GDCM_SOURCE_DIR}/Utilities/gdcmext/mec_mr3.c
+                              ${GDCM_SOURCE_DIR}/Utilities/gdcmext/mec_mr3_io.c
+                              ${GDCM_SOURCE_DIR}/Utilities/gdcmext/mec_mr3_dict.c
+                              PROPERTIES
+                              COMPILE_DEFINITIONS _POSIX_C_SOURCE=200809L
+)

 # Add the include paths
 include_directories(
   "${GDCM_SOURCE_DIR}/Source/Common"
   "${GDCM_BINARY_DIR}/Source/Common"
   "${GDCM_SOURCE_DIR}/Source/DataStructureAndEncodingDefinition"
   "${GDCM_SOURCE_DIR}/Source/DataDictionary"

Please note that the two changes on line 123 and 132 respectively are optional. But it seems it would be more consistent to use COMPILE_DEFINITIONS in all of these cases.

Discussion

  • Oliver Schneider

    I forgot to mention the command line I use:

    • preparational cleaning: rm -rf -- _build _output
    • CMake generator step: env CFLAGS="-std=c17" CC=clang CXX=clang++ cmake -S . -B _build -DCMAKE_INSTALL_PREFIX=_output -DBUILD_SHARED_LIBS=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DCMAKE_C_COMPILER_LAUNCHER=sccache -DGDCM_USE_SYSTEM_ZLIB=ON -DGDCM_USE_SYSTEM_EXPAT=ON
    • Actual build: cmake --build _build --config Release

    As one long copypasta line:

    rm -rf -- _build _output; env CFLAGS="-std=c17" CC=clang CXX=clang++ cmake -S . -B _build -DCMAKE_INSTALL_PREFIX=_output -DBUILD_SHARED_LIBS=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DCMAKE_C_COMPILER_LAUNCHER=sccache -DGDCM_USE_SYSTEM_ZLIB=ON -DGDCM_USE_SYSTEM_EXPAT=ON  && cmake --build _build --config Release
    
     

Log in to post a comment.

MongoDB Logo MongoDB