Skip to content

Commit bb9acc6

Browse files
JohnsterIDxezon
authored andcommitted
fix(calling-convention): Standardize calling conventions and variadic macros (#2067)
Standardize function calling conventions and variadic macro definitions for MinGW-w64 compatibility. Changes: - Add missing __cdecl to function pointers in GameText.h - Fix VA_ARGS macro definitions to use __VA_ARGS__ properly - Ensure consistent calling conventions across platforms This resolves calling convention mismatches that could cause undefined behavior when crossing DLL boundaries or using variadic macros with MinGW-w64.
1 parent 7c6cd35 commit bb9acc6

4 files changed

Lines changed: 18 additions & 6 deletions

File tree

Generals/Code/GameEngine/Include/GameClient/GameText.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,18 +110,24 @@ extern GameTextInterface* CreateGameTextInterface( void );
110110
// TheGameText->FETCH_OR_SUBSTITUTE("GUI:LabelName", L"Substitute Fallback Text")
111111
// TheGameText->FETCH_OR_SUBSTITUTE_FORMAT("GUI:LabelName", L"Substitute Fallback Text %d %d", 1, 2)
112112
// The substitute text will be compiled out if ENABLE_GAMETEXT_SUBSTITUTES is not defined.
113+
//
114+
// Note: ##__VA_ARGS__ handles zero variadic arguments by removing the preceding comma when empty.
115+
// Example: FETCH_OR_SUBSTITUTE_FORMAT("Label", L"Text") expands correctly without trailing comma.
116+
// Without ##, it would expand to fetchOrSubstituteFormat("Label", L"Text",) causing a syntax error.
117+
// This extension is widely supported (GCC, Clang, MSVC 2015+). C++20 __VA_OPT__ is the standard
118+
// alternative, but ##__VA_ARGS__ is simpler and compatible across C++11/14/17/20.
113119
#if ENABLE_GAMETEXT_SUBSTITUTES
114120

115121
#define FETCH_OR_SUBSTITUTE(labelA, substituteTextW) fetchOrSubstitute(labelA, substituteTextW)
116122
#if __cplusplus >= 201103L // TheSuperHackers @todo Remove condition when abandoning VC6
117-
#define FETCH_OR_SUBSTITUTE_FORMAT(labelA, substituteFormatW, ...) fetchOrSubstituteFormat(labelA, substituteFormatW, __VA_ARGS__)
123+
#define FETCH_OR_SUBSTITUTE_FORMAT(labelA, substituteFormatW, ...) fetchOrSubstituteFormat(labelA, substituteFormatW, ##__VA_ARGS__)
118124
#endif
119125

120126
#else
121127

122128
#define FETCH_OR_SUBSTITUTE(labelA, substituteTextW) fetch(labelA)
123129
#if __cplusplus >= 201103L // TheSuperHackers @todo Remove condition when abandoning VC6
124-
#define FETCH_OR_SUBSTITUTE_FORMAT(labelA, substituteTextW, ...) fetchFormat(labelA, __VA_ARGS__)
130+
#define FETCH_OR_SUBSTITUTE_FORMAT(labelA, substituteFormatW, ...) fetchFormat(labelA, ##__VA_ARGS__)
125131
#endif
126132

127133
#endif // ENABLE_GAMETEXT_SUBSTITUTES

Generals/Code/GameEngine/Source/GameClient/GameText.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ class GameTextManager : public GameTextInterface
199199
Char readChar( File *file );
200200
};
201201

202-
static int _cdecl compareLUT ( const void *, const void*);
202+
static int __cdecl compareLUT ( const void *, const void*);
203203
//----------------------------------------------------------------------------
204204
// Private Data
205205
//----------------------------------------------------------------------------

GeneralsMD/Code/GameEngine/Include/GameClient/GameText.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,18 +110,24 @@ extern GameTextInterface* CreateGameTextInterface( void );
110110
// TheGameText->FETCH_OR_SUBSTITUTE("GUI:LabelName", L"Substitute Fallback Text")
111111
// TheGameText->FETCH_OR_SUBSTITUTE_FORMAT("GUI:LabelName", L"Substitute Fallback Text %d %d", 1, 2)
112112
// The substitute text will be compiled out if ENABLE_GAMETEXT_SUBSTITUTES is not defined.
113+
//
114+
// Note: ##__VA_ARGS__ handles zero variadic arguments by removing the preceding comma when empty.
115+
// Example: FETCH_OR_SUBSTITUTE_FORMAT("Label", L"Text") expands correctly without trailing comma.
116+
// Without ##, it would expand to fetchOrSubstituteFormat("Label", L"Text",) causing a syntax error.
117+
// This extension is widely supported (GCC, Clang, MSVC 2015+). C++20 __VA_OPT__ is the standard
118+
// alternative, but ##__VA_ARGS__ is simpler and compatible across C++11/14/17/20.
113119
#if ENABLE_GAMETEXT_SUBSTITUTES
114120

115121
#define FETCH_OR_SUBSTITUTE(labelA, substituteTextW) fetchOrSubstitute(labelA, substituteTextW)
116122
#if __cplusplus >= 201103L // TheSuperHackers @todo Remove condition when abandoning VC6
117-
#define FETCH_OR_SUBSTITUTE_FORMAT(labelA, substituteFormatW, ...) fetchOrSubstituteFormat(labelA, substituteFormatW, __VA_ARGS__)
123+
#define FETCH_OR_SUBSTITUTE_FORMAT(labelA, substituteFormatW, ...) fetchOrSubstituteFormat(labelA, substituteFormatW, ##__VA_ARGS__)
118124
#endif
119125

120126
#else
121127

122128
#define FETCH_OR_SUBSTITUTE(labelA, substituteTextW) fetch(labelA)
123129
#if __cplusplus >= 201103L // TheSuperHackers @todo Remove condition when abandoning VC6
124-
#define FETCH_OR_SUBSTITUTE_FORMAT(labelA, substituteTextW, ...) fetchFormat(labelA, __VA_ARGS__)
130+
#define FETCH_OR_SUBSTITUTE_FORMAT(labelA, substituteFormatW, ...) fetchFormat(labelA, ##__VA_ARGS__)
125131
#endif
126132

127133
#endif // ENABLE_GAMETEXT_SUBSTITUTES

GeneralsMD/Code/GameEngine/Source/GameClient/GameText.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ class GameTextManager : public GameTextInterface
199199
Char readChar( File *file );
200200
};
201201

202-
static int _cdecl compareLUT ( const void *, const void*);
202+
static int __cdecl compareLUT ( const void *, const void*);
203203
//----------------------------------------------------------------------------
204204
// Private Data
205205
//----------------------------------------------------------------------------

0 commit comments

Comments
 (0)