We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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)'
Experiments:
template< typename Type > int func( Type as, float fl=(float)(NAN) ); //fail template< typename Type > int func( Type as, float fl=0f_7FC00000 ); // Compiled. No error template< typename Type > int func( Type as, float fl=__ESCAPE__(0f_7FC00000) ); //fail
The problem appears to be that the C++ compiler does not recognize the (undocumented?) compiler intrinsic __ESCAPE__ early enough in the parsing process to decipher this expression.
I've found this thread about __ESCAPE__ http://www.keil.com/forum/9630/ It seems problem may be solved with declaring
#define __ESCAPE__(__x) (__x)
I will test soon.
That makes __ESCAPE into a null operation. But the question then is what functionality that gets lost - because ARM must have had some intention with the __ESCAPE() construct.
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.