You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
MSVC compilation error caused by macro conflict with `std::numeric_limits<T>::max()`
16
+
17
+
The error occurred at two locations in the argument parsing code (the `-p` port and `-D` debug level options):
18
+
19
+
```cpp
20
+
// Original code (problematic)
21
+
if ( val > std::numeric_limits<unsignedshort>::max() )
22
+
throwstd::out_of_range( "port out of range" );
23
+
```
24
+
25
+
### Root Cause
26
+
27
+
Windows headers (particularly `windows.h` and related headers) often define `max` and `min` as preprocessor macros:
28
+
29
+
```cpp
30
+
#define max(a,b) (((a) > (b)) ? (a) : (b))
31
+
```
32
+
33
+
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.
34
+
35
+
### Solution
36
+
37
+
Wrap the function name in parentheses to prevent macro expansion:
38
+
39
+
```cpp
40
+
// Fixed code
41
+
if ( val > (std::numeric_limits<unsignedshort>::max)() )
42
+
throwstd::out_of_range( "port out of range" );
43
+
```
44
+
45
+
By adding parentheses around `max`, the preprocessor no longer recognizes it as a macro invocation, allowing the actual member function to be called.
46
+
47
+
### Technical Details
48
+
49
+
- **Affected code:** Port validation (`-p` option) and debug level validation (`-D` option)
50
+
- **Context:** Command-line argument parsing for `-p` (port) and `-D` (debug level) options
51
+
- **Alternative solutions:**
52
+
1. `#undef max` before use (not recommended, affects entire translation unit)
53
+
2. Define `NOMINMAX` before including Windows headers (project-wide change)
54
+
3. Use `(std::numeric_limits<T>::max)()` (chosen solution - local and surgical)
55
+
56
+
### Why This Approach
57
+
58
+
The parentheses-wrapping approach is preferred because:
59
+
1. **Minimal impact:** Only affects the specific call sites
60
+
2. **No side effects:** Doesn't disable macros for other code that might depend on them
61
+
3. **Clear intent:** Documents that macro expansion is being avoided
62
+
4. **Standard practice:** Commonly used pattern in cross-platform C++ code
63
+
64
+
### Best Practices
65
+
66
+
When writing portable C++ code that may be compiled with Windows headers:
67
+
- Always wrap standard library function names like `min`, `max` in parentheses when calling them
68
+
- Consider using `(std::min)(a, b)` and `(std::max)(a, b)` for function calls, and `(std::numeric_limits<T>::max)()` for `numeric_limits`
69
+
- Be aware that macros from platform headers can interfere with identically-named functions
0 commit comments