I have got an error message with next code
template< typename Type > int func( Type as, float fl=NAN );
error: #109: expression preceding parentheses of apparent call must have (pointer-to-) function type
It seems the problem is with resolving NAN, defined in math.h at line 249
# define NAN (__ESCAPE__(0f_7FC00000))
There is no problem if no NAN used
template< typename Type > int func( Type as, float fl=0 );
There is no problem if template not used
int func( int as, float fl=NAN );
There is no problem with GCC.
Compilier version
*** Using Compiler 'V5.05 update 2 (build 169)'
ARM must have had some intention with the __ESCAPE() construct.
Evidently. But the only description of it that you'll find is very vague about what it actually does. They only tell it's a compiler builtin, and that it's used to hide usages of non-standard features from standard-picky modes of the compiler. I.e. they explain the why, but not the how.
#define-ing it away is supposed to only be needed for compilers other than ARMCC using ARM's <math.h> or <limits.h>. Why one would do that is beyond my tolerance for utter nonsense. :->
As it is, this is a failure of ARM's headers to play nice with ARM's compiler. In other words: this a compiler bug worth reporting to support.
Ah - so basically it already is a no-op.
It's expected to be 100% transparent when compiling with the ARM compiler - just "unit expansion" of the argument(s).
While it's expected to expand to nothing at all for "non-compliant" compilers.
So with the ARM compiler:
int func( Type as, float fl=0f_7FC00000 );
And with another compiler:
int func( Type as, float fl= );
But that would mean that the "=" should have been inside the __ESCAPE__, or the "non-compliant" compilers that doesn't support this 0f_7FC00000 hexadecimal floating-point value will still fail to compile.
It feels like the __ESCAPE__ construct was a design that failed before it left the drawing board.
Not quite. ARM wouldn't have to go this far out of their way just to create a no-op. Just writing nothing at all would have the same effect.
No. With any other compiler, you get.
int func( Type as, float fl= __ESCAPE__(0f_7FC00000) );
What that actually turns into depends entirely on what the user of the alien compiler decides to #define __ESCAPE__ as to fix this obvious syntax error.
But OTOH that alien compiler would surely come with its own <math.h>. So there should never be a need to pull in the one from ARMCC's system include file collection.
Using another implementation's Standard C Library headers is a Bad Thing, and one should fully expect bad things to happen because of it. As I take it, this macro may be just an elaborate, circuitous way of expressing "Here Be Dragons".
So, does anybody have bright idea and better solution than
#ifdef __CC_ARM #undef NAN #define NAN (0f_7FC00000) #endif
or even
#ifdef __CC_ARM #undef __ESCAPE__ #define __ESCAPE__ #endif
?
The only actual solution to this is for Keil/ARM to find.
It's ARM's own header file, and ARM's own compiler, so if combining the two in a slightly unusual fashion causes a problem, that's ARM's problem to solve. So have you filed a support request yet?
Until then, your best bet at a temporary workaround would probably be one of those you showed.
Yet another...
#include <cmath> class Cla { float h = NAN; // error: #65: expected a ";" };
What's the f... The medicine is same
#include <cmath> #ifdef __CC_ARM // ARM CC bug http://www.keil.com/forum/60227/ #define __ESCAPE__(__x) (__x) #endif
All files compiled with --cpp11.