Topic: concatenation of power of negative number


Author: andy@servocomm.freeserve.co.uk
Date: Fri, 20 Jan 2006 12:18:03 CST
Raw View
Hi,

Using gcc3.2  the concatenation of  1##Num  where Num is negative
leaves a space
eg 1e#-1  --> 1e -1 as can be seen by the preprocessed output below.
The only
way round it  that I can see is to simply not use a macro for this
compiler, which means producing some 200 specialisations by hand

Is this  the correct behaviour? I believe that  the relevant part is
16.3.3.-3 where it says that "if the result (of concatenation) is not a
valid preprocessing token the behaviour is undefined." I think that the
relevent production is:

pp_number <- pp_number e sign

pp_number <-pp_number digit

So  (though my dealings with grammars are often suspect) I would expect
this to be a valid preprocessor operation. Now if it isnt, it is
awfully inconvenient when trying to use this particular number format
in this way. Any help on this would be appreciated.

#define POW_EVAL(Num, Float_type)\
       template <>\
       struct pow_eval< \
            Float_type BOOST_PP_COMMA()  Num  BOOST_PP_COMMA()\
             1 BOOST_PP_COMMA() false\
             >{\
           enum{ required = true};\
           typedef Float_type result_type;\
           result_type operator()()const\
           {    result_type result\
                = static_cast< Float_type > (1e ## Num);\
                return result;\
            }\
       };

POW_EVAL(-60, double)
POW_EVAL(-59, double)
POW_EVAL(58, double)
POW_EVAL(57, double)

// preprocessor output.  note the space in e.g static_cast<double>(1e-
60)

template <> struct pow_eval< double , -60 , 1 , false >{ enum{ required
= true};
typedef double result_type; result_type operator()()const { result_type
result =
static_cast< double > (1e- 60); return result; } };
template <> struct pow_eval< double , -59 , 1 , false >{ enum{ required
= true};
typedef double result_type; result_type operator()()const { result_type
result =
static_cast< double > (1e- 59); return result; } };
template <> struct pow_eval< double , 58 , 1 , false >{ enum{ required
= true};
typedef double result_type; result_type operator()()const { result_type
result =
static_cast< double > (1e58); return result; } };
template <> struct pow_eval< double , 57 , 1 , false >{ enum{ required
= true};
typedef double result_type; result_type operator()()const { result_type
result =
static_cast< double > (1e57); return result; } };

regards
Andy Little

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pmenso57@comcast.net ("Paul Mensonides")
Date: Fri, 20 Jan 2006 23:00:12 GMT
Raw View
<andy@servocomm.freeserve.co.uk> wrote in message
news:1137779816.702282.199460@g43g2000cwa.googlegroups.com...
> Hi,
>
> Using gcc3.2  the concatenation of  1##Num  where Num is negative
> leaves a space
> eg 1e#-1  --> 1e -1 as can be seen by the preprocessed output below.

gcc gives 1e- 1 which is correct.  You aren't concatenating 1e to the "token" -1
(-1 is two tokens) you're concatenating 1e just the - token.  I.e.

 <1e> ## <-> <1>
|___________|
      |
      token pasting only affects these two preprocessing tokens

There is no way to do this directly, but you can form (e.g) 1e-1 by a double
concatenation:

#define CAT(a, b) PRIMITIVE_CAT(a, b)
#define PRIMITIVE_CAT(a, b) a ## b

CAT(PRIMITIVE_CAT(1e, -), 1) // 1e-1

Regards,
Paul Mensonides


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]