Re: C++ and packed decimal strange behavior
Jevgeni Astanovski <[email protected]>
| Newsgroups | gmane.comp.lang.as400.c |
|---|---|
| Message-ID | <CAJuVQr0-_JLoWM5YSkMV0Ct4m=RX4fDLJzterfww6fVhp3RNEg@mail.gmail.com> |
Hi Jarod,
First of all thanks for clarification. I expected that what works in C will
also work in C++ - invalid assumption at least with packed decimals...
Did I understood correctly that the problem is based on the fact that
compiler has no ways to decide either to convert decimal(17.0) to
decimal(16,0) or vice versa?
Assuming that I made 3 experiments: two with positive results, one with
negative.
This works:
v1 = (memcmp(Day1, Day2, 7) <= 0) ?
(decimal (15,0)) (v2 - v3 - v4) :
(decimal (15,0)) (v2 - v4 ) ;
probably because both E1 and E2 are cast to decimal (15,0) explicitly.
This works:
...
decimal (15,0) v5 ;
v5 = __D("0") ;
v1 = (memcmp(Day1, Day2, 7) <= 0) ?
v2 - v3 - v4 :
v2 - v4 - v5 ;
because both E1 and E2 are already decimal (17,0).
And this does not work:
#define __D("0") ;
v1 = (memcmp(Day1, Day2, 7) <= 0) ?
v2 - v3 - v4 :
v2 - v4 - ZERO ;
with an error message
CZP0207 No common type found for operands with type "_DecimalT<17,0>" and
"_ConvertDecimal".
Thanks again,
Jevgeni.
On Tue, Jul 21, 2015 at 8:38 PM, Qian Ren <[email protected]> wrote:
> Jevgeni Astanovski <jevgeniast@...> writes:
>
> >
> > Hi, all.
> > I'm really new with C++ and recently while porting a program from ILE/C
> to
> > ILE/C++ ran into a strange effect that I cannot explain. Maybe someone
> can
> > help me.
> >
> > Here's a simple program:
> >
> > #include <stdlib.h>
> > #include <bcd.h>
> >
> > int main (int argc, char *argv[])
> > {
> > char Day1[7], Day2[7] ;
> > _DecimalT<15, 0> v1, v2, v3, v4 ;
> >
> > memset (Day1, '0', 7) ;
> > memset (Day2, '1', 7) ;
> >
> > v2 = __D("100") ;
> > v3 = __D("10") ;
> > v4 = __D("200") ;
> >
> > v1 = (memcmp(Day1, Day2, 7) <= 0) ? v2 - v3 - v4 : v2 - v4 ;
> >
> > return(0) ;
> > }
> >
> > Attempt to compile it produces error message for conditional assignment:
> > CZP0207 No common type found for operands with type "_DecimalT<17,0>" and
> > "_DecimalT<16,0>".
> >
> > However when I change it (put a plain conditional statement):
> >
> > #include <stdlib.h>
> > #include <bcd.h>
> >
> > int main (int argc, char *argv[])
> > {
> > char Day1[7], Day2[7] ;
> > _DecimalT<15, 0> v1, v2, v3, v4 ;
> >
> > memset (Day1, '0', 7) ;
> > memset (Day2, '1', 7) ;
> >
> > v2 = __D("100") ;
> > v3 = __D("10") ;
> > v4 = __D("200") ;
> >
> > if (memcmp(Day1, Day2, 7) <= 0)
> > v1 = v2 - v3 - v4 ;
> > else
> > v1 = v2 - v4 ;
> >
> > return(0) ;
> > }
> >
> > Program compiles fine without errors...
> >
> > In ILE/C both compile, of course....
> >
> > What is the difference?
> >
> > TIA,
> >
> > Jevgeni.
>
>
> Hi Jevgeni,
>
> According to the C++ standard (section 5.16 Conditional operator), the
> expression "(memcmp(Day1, Day2, 7) <= 0) ? v2 - v3 - v4 : v2 - v4" is
> ill-formed.
>
> For a conditional expression "condition? E1 : E2", if the E1 and E2 have
> different types, an attempt is made to convert each of them to the type of
> the other(5.16.3). The type of expression "v2-v3-v4" is _DecimalT<17, 0>.
> And the type of expression "v2-v4" is _DecimalT<16, 0>. So compiler will
> try to convert the type of "v2-v3-v4" to _DecimalT<16, 0> and try to
> convert
> the type of "v2-v4" to _DecimalT<17, 0>.
>
> The bcd.h header file defines the following constructor of template class
> _DecimalT. So each of "v2-v3-v4" and "v2-v4" can be converted to the type
> of other. And according to the standard, if both E1 and E2 can be
> converted, or one can be converted but the conversion is ambiguous, the
> program is ill-formed (5.16.3).
>
> template<int dig, int prec>
> template<int dig2, int prec2>
> inline _DecimalT<dig,prec>::_DecimalT (const _DecimalT<dig2, prec2>
> val) {
> ......
> }
>
> I think another possible work around is to change the statement to
> "(memcmp(Day1, Day2, 7) <= 0) ? v1 = v2 - v3 - v4 : v1 = v2 - v4;".
>
> Here is the link of the C++ stardand draft
> (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf). You
> could read section 5.16 for details.
>
> Thank you.
>
> Qian Ren (Jarod)
>
> --
> This is the Bare Metal Programming IBM i (AS/400 and iSeries) (C400-L)
> mailing list
> To post a message email: C400-L-Zwy7GipZuJhWk0Htik3J/[email protected]
> To subscribe, unsubscribe, or change list options,
> visit: http://lists.midrange.com/mailman/listinfo/c400-l
> or email: C400-L-request-Zwy7GipZuJhWk0Htik3J/[email protected]
> Before posting, please take a moment to review the archives
> at http://archive.midrange.com/c400-l.
>
>
--
This is the Bare Metal Programming IBM i (AS/400 and iSeries) (C400-L) mailing list
To post a message email: C400-L-Zwy7GipZuJhWk0Htik3J/[email protected]
To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/c400-l
or email: C400-L-request-Zwy7GipZuJhWk0Htik3J/[email protected]
Before posting, please take a moment to review the archives
at http://archive.midrange.com/c400-l.