This document tracks code improvements made with the assistance of AI agents.
Note: For compilation instructions, see README.md.
Commit: 2e387a11
Date: 2026-04-06
File: src/pcm-sensor-server.cpp
MSVC compilation error caused by macro conflict with std::numeric_limits<T>::max()
The error occurred at two locations in the argument parsing code (the -p port and -D debug level options):
// Original code (problematic)
if ( val > std::numeric_limits<unsigned short>::max() )
throw std::out_of_range( "port out of range" );Windows headers (particularly windows.h and related headers) often define max and min as preprocessor macros:
#define max(a,b) (((a) > (b)) ? (a) : (b))When the preprocessor encounters std::numeric_limits<unsigned short>::max(), the max() part gets expanded as a macro, resulting in malformed code that fails to compile.
Wrap the function name in parentheses to prevent macro expansion:
// Fixed code
if ( val > (std::numeric_limits<unsigned short>::max)() )
throw std::out_of_range( "port out of range" );By adding parentheses around max, the preprocessor no longer recognizes it as a macro invocation, allowing the actual member function to be called.
- Affected code: Port validation (
-poption) and debug level validation (-Doption) - Context: Command-line argument parsing for
-p(port) and-D(debug level) options - Alternative solutions:
#undef maxbefore use (not recommended, affects entire translation unit)- Define
NOMINMAXbefore including Windows headers (project-wide change) - Use
(std::numeric_limits<T>::max)()(chosen solution - local and surgical)
The parentheses-wrapping approach is preferred because:
- Minimal impact: Only affects the specific call sites
- No side effects: Doesn't disable macros for other code that might depend on them
- Clear intent: Documents that macro expansion is being avoided
- Standard practice: Commonly used pattern in cross-platform C++ code
When writing portable C++ code that may be compiled with Windows headers:
- Always wrap standard library function names like
min,maxin parentheses when calling them - Consider using
(std::min)(a, b)and(std::max)(a, b)for function calls, and(std::numeric_limits<T>::max)()fornumeric_limits - Be aware that macros from platform headers can interfere with identically-named functions