Front page | perl.perl5.porters |
Postings from December 2012
Re: SvUPGRADE and void
Thread Previous
|
Thread Next
From:
Craig A. Berry
Date:
December 14, 2012 18:24
Subject:
Re: SvUPGRADE and void
Message ID:
CA+vYcVyD7NufJEupbBOu_ygNbJkvVxH6+WYMQ=gJvp3jD2LnPw@mail.gmail.com
On Fri, Dec 14, 2012 at 11:48 AM, Dave Mitchell <davem@iabyn.com> wrote:
> On Fri, Dec 14, 2012 at 03:22:15PM +0000, Dave Mitchell wrote:
>> On Fri, Dec 14, 2012 at 01:22:42PM +0000, Nicholas Clark wrote:
>> > On Thu, Dec 13, 2012 at 01:14:28PM +0000, Dave Mitchell wrote:
>> >
>> > > The first is to stick a (void) in front of every bare SvUPGRADE() in the
>> > > the perl distribution (including dist/ and, via rt.cpan.org, cpan/).
>> > > This seems like quite a bit of effort and is a retrograde step.
>> >
>> > And, arguably, on every distribution on CPAN that also generates a warning?
>> >
>> > > The second is to bite the bullet and change SvUPGRADE from an expression
>> > > into a statement; i.e.
>> > >
>> > > #define SvUPGRADE(sv, mt) (SvTYPE(sv) >= (mt) || (sv_upgrade(sv, mt), 1))
>> > >
>> > > becomes
>> > >
>> > > #define SvUPGRADE(sv, mt) if (sv->type >= (mt)) { sv_upgrade(sv, mt); }
>> > >
>> > > A search for 'if.*SvUPGRADE' on grep.cpan.me indicates that about 15
>> > > distributions would fail to compile and need fixing.
>> > >
>> > > I'm open to other suggestions.
>> >
>> > I think we should bit the bullet and go for it. For anything that needs
>> > changing, it's a build-time error from the C compiler? (with an easy fix)
>> > That's not going to break anything in production.*
>>
>> Ok, I've bitten the bullet.
>
> ... and broken g++.
>
> Can anyone suggest a definition for SvUPGRADE that works for both of the
> forms
>
> SvUPGRADE(...);
> (void)SvUPGRADE(...);
>
> on gcc, clang and g++, and doesn't generate warnings?
>
> My new incarnation,
>
> #define SvUPGRADE(sv, mt) \
> STMT_START { if (SvTYPE(sv) < (mt)) sv_upgrade(sv, mt); } STMT_END
>
> which expands this this line in regcomp.c:
>
> (void)SvUPGRADE(sv_dat,SVt_PVNV);
>
> into:
>
> (void)do { if (((svtype)((sv_dat)->sv_flags & 0xff)) < (SVt_PVNV)) Perl_sv_upgrade(my_perl, sv_dat,SVt_PVNV); } while (0);
>
> gives this error under g++:
>
> regcomp.c:8653:35: error: expected primary-expression before ‘do’
> regcomp.c:8653:35: error: expected ‘;’ before ‘do’
>
> while the old version:
>
> #define SvUPGRADE(sv, mt) (SvTYPE(sv) >= (mt) || (sv_upgrade(sv, mt), 1))
>
> gave warnings under clang for this form:
>
> SvUPGRADE(...);
The following satisfies the VMS C compiler. Not sure what it does for
clang and won't have a chance to try for a few hours.
$ gdiff -pu sv.h;-0 sv.h
--- sv.h;-0 2012-12-14 09:18:20 -0600
+++ sv.h 2012-12-14 12:05:37 -0600
@@ -328,7 +328,7 @@ perform the upgrade if necessary. See C
#define SvIS_FREED(sv) ((sv)->sv_flags == SVTYPEMASK)
#define SvUPGRADE(sv, mt) \
- STMT_START { if (SvTYPE(sv) < (mt)) sv_upgrade(sv, mt); } STMT_END
+ STMT_START { if (SvTYPE(sv) < (mt)) (void)sv_upgrade(sv, mt);
} STMT_END
#define SVf_IOK 0x00000100 /* has valid public integer value */
#define SVf_NOK 0x00000200 /* has valid public numeric value */
$ gdiff -pu regcomp.c;-0 regcomp.c
--- regcomp.c;-0 2012-12-14 06:41:20 -0600
+++ regcomp.c 2012-12-14 12:20:44 -0600
@@ -8650,7 +8650,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I
SvIV_set(sv_dat, SvIVX(sv_dat) + 1);
}
} else {
- (void)SvUPGRADE(sv_dat,SVt_PVNV);
+ SvUPGRADE(sv_dat,SVt_PVNV);
sv_setpvn(sv_dat, (char *)&(RExC_npar),
sizeof(I32));
SvIOK_on(sv_dat);
SvIV_set(sv_dat, 1);
Thread Previous
|
Thread Next