Hi Paul, > > The current set of definitions > > > > #define _Noreturn __declspec (noreturn) > > #define noreturn _Noreturn > > > > leads to a syntax error when someone writes __declspec (noreturn), > > because preprocessing transforms it to __declspec (__declspec (noreturn)). > > > > How can this syntax error be avoided? > > I don't see any reasonable way to do it.
If we could redefine __declspec, it would be possible. Like this: $ cat foo.c #define noreturn __declspec(noreturn) #define _Noreturn noreturn #define __declspec(a) __declspec1(a) #define __declspec1(a) __wrapped_##a #define __wrapped_noreturn __declspec(noreturn1) #define __wrapped_noreturn1 __declspec(noreturn) #define __wrapped___wrapped_noreturn __declspec1(noreturn2) #define __wrapped_noreturn2 noreturn __declspec(noreturn) void exit (int); noreturn void exit (int); $ cl -E foo.c ... __declspec(noreturn) void exit (int); __declspec(noreturn) void exit (int); But unfortunately there are also other possible elements in a declspec list, see [1]. I don't see how to accommodate these. And interestingly, this preprocessor output from 'cl' is different from the one that gcc produces. With gcc, it's easier: $ cat foo.c #define noreturn __declspec(noreturn) #define _Noreturn noreturn #define __declspec(a) __wrapped_##a #define __wrapped_noreturn __attribute__((__noreturn__)) __declspec(noreturn) void exit (int); noreturn void exit (int); $ gcc -E foo.c ... __attribute__((__noreturn__)) void exit (int); __attribute__((__noreturn__)) void exit (int); Bruno [1] http://msdn.microsoft.com/en-us/library/dabb5z75%28v=vs.80%29.aspx