I also noticed the TAG_DONE) trick.
I looked at the preprocessor output using "i386-aros-gcc -E":
...
int main(void)
{
MUIMasterBase = __inline_Exec_OpenLibrary(((STRPTR)"muimaster.library"), (0), (SysBase));
if (MUIMasterBase == ((void *)0)) {
printf("No MUI\n");
return 10;
}
struct MUI_CustomClass *mcc =
__inline_MUIMaster_MUI_CreateCustomClass((((void *)0)), ((STRPTR)"Rectangle.mui"), (((void *)0)), (0), (((void *)0)), (MUIMasterBase));
MyClass = mcc->mcc_Class;
Object *app = MUI_NewObject("Application.mui", (0UL));
Object *obj =
# 378 "/usr/local/aros-sdk/SDK-alt-abiv0-i386/include/libraries/mui.h" 3 4
NewObject
and it simply stops in the middle of the " Object *obj = MyObject, End;" line
My hypothesis is that this is because NewObject itself is also a macro, so the pre-processor wants to find a closing parenthesis for doing the textual replacement of NewObject, but it hasn't processed the "End" define yet, and therefore fails. Reading
https://gcc.gnu.org/onlinedocs/cppinternals/Macro-Expansion.html it seems the pre-processing algorithm is such that it first wants to replace the NewObject macro before the End define, thus this might be working as intended.
I guess this means, one has one of the two choices:
- Use the MyObject, ApplicationObject, End, etc. defines but turn off inlining NewObject and MUI_NewObject through NO_INLINE_STDARG, or
- Don't use these defines and call NewObject and MUI_NewObject directly, or use TAG_DONE) instead of End.
I think most code uses 1., thus maybe NO_INLINE_STDARG should be set as the default somewhere. This also means AROS uses the AROS_SLOWSTACK code for both NewObject and MUI_NewObject.