From cc2c016f3432d9d4f7daf768c790075a204895c0 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 29 Jul 2026 20:30:20 +0300 Subject: [PATCH] Fix error C2020: 'parms': 'struct' member redefinition (shared/minwindef.h) defines the legacy 16 bit memory model keywords "near" and "far" as empty macros. In any translation unit that includes it ahead of spandsp/expose.h, that strips the names from the near and far members of struct v150_1_state_s: struct { v150_1_near_far_t parms; ... } ; /* was } near; */ struct { v150_1_near_far_t parms; ... } ; /* was } far; */ MSVC then treats both as anonymous structs and flattens their members into the enclosing struct, where the two "parms" members collide. The error names "parms" rather than near/far because those tokens are gone before the compiler sees them. Undefine both macros around the struct in private/v150_1.h, restoring them with #pragma pop_macro at the end of the header. private/v150_1.h is an installed header, so it must not leave a consumer's macro state altered. v150_1.c refers to the members by name and is the only file that does, so it undefines the macros locally after its includes. --- src/spandsp/private/v150_1.h | 19 +++++++++++++++++++ src/v150_1.c | 8 ++++++++ 2 files changed, 27 insertions(+) diff --git a/src/spandsp/private/v150_1.h b/src/spandsp/private/v150_1.h index 68c60767..cd658678 100644 --- a/src/spandsp/private/v150_1.h +++ b/src/spandsp/private/v150_1.h @@ -26,6 +26,20 @@ #if !defined(_SPANDSP_PRIVATE_V150_1_H_) #define _SPANDSP_PRIVATE_V150_1_H_ +#if defined(_WIN32) +/* (minwindef.h) defines the legacy 16 bit memory model keywords + "near" and "far" as empty macros. Left in place, they strip the names from + the near and far members of v150_1_state_s, making them anonymous structs. + MSVC then flattens their contents into the enclosing struct, where the two + "parms" members collide (error C2020: 'parms': 'struct' member + redefinition). Both macros are restored at the end of this header, so an + including application keeps whatever it had. */ +#pragma push_macro("near") +#pragma push_macro("far") +#undef near +#undef far +#endif + /* telephone network ^ @@ -361,5 +375,10 @@ struct v150_1_state_s logging_state_t logging; }; +#if defined(_WIN32) +#pragma pop_macro("far") +#pragma pop_macro("near") +#endif + #endif /*- End of file ------------------------------------------------------------*/ diff --git a/src/v150_1.c b/src/v150_1.c index 03fc64c3..01560b99 100644 --- a/src/v150_1.c +++ b/src/v150_1.c @@ -56,6 +56,14 @@ #include "v150_1_local.h" +#if defined(_WIN32) +/* See the note in spandsp/private/v150_1.h. The near and far members of + v150_1_state_t are referenced by name throughout this file, so the + macros of those names must not be in effect here. */ +#undef near +#undef far +#endif + /* Terminology V.150.1 has several components. The terms used for these are: