如何用CMake确定64位有符号整数类型及printf格式说明符
Got it, let's work through this problem together. You want to detect a 64-bit signed integer type and its matching printf format specifier for your C project, without assuming stdint.h is available—all using your existing CMake setup. Here's how to make that happen:
First, we'll expand your existing CMake code to check for common 64-bit signed integer candidates and validate which printf specifier works with the detected type. Add these lines to your CMakeLists.txt right after your existing include(CheckIncludeFiles) and configure_file calls:
# Check size of potential 64-bit signed integer types include(CheckTypeSize) check_type_size("long long" SIZEOF_LONG_LONG) check_type_size("long" SIZEOF_LONG) check_type_size("__int64" SIZEOF___INT64) check_type_size("int64_t" SIZEOF_INT64_T) # Determine which type is 64 bits wide if(SIZEOF_LONG_LONG EQUAL 8) set(INT64_TYPE "long long") elseif(SIZEOF_LONG EQUAL 8) set(INT64_TYPE "long") elseif(SIZEOF___INT64 EQUAL 8) set(INT64_TYPE "__int64") elseif(SIZEOF_INT64_T EQUAL 8) set(INT64_TYPE "int64_t") else() message(FATAL_ERROR "No 64-bit signed integer type found on this platform!") endif() # Detect the correct printf format specifier for the type include(CheckCSourceCompiles) # Test "%lld" (common for long long) check_c_source_compiles(" #include <stdio.h> int main() { ${INT64_TYPE} x = 0; printf(\"%lld\", x); return 0; } " HAS_PRINTF_LLD) # Test "%ld" (for long when it's 64 bits) check_c_source_compiles(" #include <stdio.h> int main() { ${INT64_TYPE} x = 0; printf(\"%ld\", x); return 0; } " HAS_PRINTF_LD) # Test "%I64d" (MSVC's specifier for __int64) check_c_source_compiles(" #include <stdio.h> int main() { ${INT64_TYPE} x = 0; printf(\"%I64d\", x); return 0; } " HAS_PRINTF_I64D) # Set the valid specifier if(HAS_PRINTF_LLD) set(INT64_PRINTF_SPECIFIER "%lld") elseif(HAS_PRINTF_LD) set(INT64_PRINTF_SPECIFIER "%ld") elseif(HAS_PRINTF_I64D) set(INT64_PRINTF_SPECIFIER "%I64d") else() message(FATAL_ERROR "No valid printf specifier found for 64-bit integer type!") endif()
Modify your config.h.in to expose the detected type and specifier with familiar names (matching stdint.h conventions for ease of use):
/* 64-bit signed integer type (equivalent to stdint.h's int64_t) */ #cmakedefine INT64_TYPE @INT64_TYPE@ #define int64_t INT64_TYPE /* Printf format specifier for int64_t (equivalent to stdint.h's PRId64) */ #cmakedefine INT64_PRINTF_SPECIFIER "@INT64_PRINTF_SPECIFIER@" #define PRId64 INT64_PRINTF_SPECIFIER
Now you can use these definitions just like you would with stdint.h:
#include "config.h" #include <stdio.h> int main() { int64_t large_number = 123456789012345LL; printf("My 64-bit number: " PRId64 "\n", large_number); return 0; }
Key Notes
- We cover major platforms: Linux/macOS (uses
long longand%lld), 32-bit systems wherelongis 64 bits, and Windows/MSVC (uses__int64and%I64d). - The
CheckTypeSizeandCheckCSourceCompilesmodules are standard in CMake, so they'll work on most systems. - If you need to handle 32-bit-only platforms, you can replace the fatal error with a fallback (like using
longeven if it's 32 bits), but this setup prioritizes finding a true 64-bit type.
内容的提问来源于stack exchange,提问作者einpoklum

