Mailing List Archive

XSUB.h warnings/patch
As I noted a few weeks ago, I was getting warnings from the Sun C compiler
on solaris when I used XSRETURN_UNDEF in my extensions. This do...while(0)
wrapper is being used all over the Perl source, as Larry pointed out, so it
seemed odd that I would see the errors only in extensions. The warning is
printed because the XSUB.h wrappers have 'return' inside them.

This patch moves the return outside the wrapper. My extensions now compile
quietly (sure, they still work :). Apply over 5.002beta1. (Are the
wrappers still necessary?)

Dean


*** XSUB.h Fri Nov 10 12:11:02 1995
--- ../patches/XSUB.h Sun Dec 3 12:55:22 1995
***************
*** 15,21 ****

#define dXSI32 I32 ix = XSANY.any_i32

! #define XSRETURN(off) stack_sp = stack_base + ax + ((off) - 1); return

/* Simple macros to put new mortal values onto the stack. */
/* Typically used to return values from XS functions. */
--- 15,22 ----

#define dXSI32 I32 ix = XSANY.any_i32

! #define XSRETSTACK(off) stack_sp = stack_base + ax + ((off) - 1)
! #define XSRETURN(off) XSRETSTACK(off); return

/* Simple macros to put new mortal values onto the stack. */
/* Typically used to return values from XS functions. */
***************
*** 26,35 ****
#define XST_mYES(i) (ST(i) = &sv_yes )
#define XST_mUNDEF(i) (ST(i) = &sv_undef)

! #define XSRETURN_IV(v) do { XST_mIV(0,v); XSRETURN(1); } while (0)
! #define XSRETURN_NV(v) do { XST_mNV(0,v); XSRETURN(1); } while (0)
! #define XSRETURN_PV(v) do { XST_mPV(0,v); XSRETURN(1); } while (0)
! #define XSRETURN_NO do { XST_mNO(0); XSRETURN(1); } while (0)
! #define XSRETURN_YES do { XST_mYES(0); XSRETURN(1); } while (0)
! #define XSRETURN_UNDEF do { XST_mUNDEF(0); XSRETURN(1); } while (0)
! #define XSRETURN_EMPTY do { XSRETURN(0); } while (0)
--- 27,36 ----
#define XST_mYES(i) (ST(i) = &sv_yes )
#define XST_mUNDEF(i) (ST(i) = &sv_undef)

! #define XSRETURN_IV(v) do { XST_mIV(0,v); XSRETSTACK(1); } while (0); return
! #define XSRETURN_NV(v) do { XST_mNV(0,v); XSRETSTACK(1); } while (0); return
! #define XSRETURN_PV(v) do { XST_mPV(0,v); XSRETSTACK(1); } while (0); return
! #define XSRETURN_NO do { XST_mNO(0); XSRETSTACK(1); } while (0); return
! #define XSRETURN_YES do { XST_mYES(0); XSRETSTACK(1); } while (0); return
! #define XSRETURN_UNDEF do { XST_mUNDEF(0); XSRETSTACK(1); } while (0); return
! #define XSRETURN_EMPTY do { XSRETSTACK(0); } while (0); return
Re: XSUB.h warnings/patch [ In reply to ]
Nick Ing-Simmons <nik@tiuk.ti.com> writes:
>Dean Roehrich <roehrich@cray.com> writes:
>>
>>This patch moves the return outside the wrapper. My extensions now compile
>>quietly (sure, they still work :). Apply over 5.002beta1. (Are the
>>wrappers still necessary?)
>>
>>! #define XSRETURN_NO do { XST_mNO(0); XSRETSTACK(1); } while (0); return
>>! #define XSRETURN_YES do { XST_mYES(0); XSRETSTACK(1); } while (0); return
>
> Consider:
>
> if (some_test)
> XSRETURN_YES;
> else
> XSRETURN_NO;
>
> Becomes:
>
> if (some_test)
> do { XST_mYES(0); XSRETSTACK(1); } while (0); return
> else
> do { XST_mNO(0); XSRETSTACK(1); } while (0); return
>
> And you get syntax error on the 'else';

It's worse without the `else' -- then you *don't* get an error message,
and may not notice that there is an error.


Here is another way than `do { ... } while(0)', which keeps sun4 cc silent:

if (1) { ... } else (void)0

That too needs "unnecessary" expressions/statements, which some compiler
might warn about. So I guess there is no way to make sure there will
never be a warning. (A third way: Remove the (void)0, but then gcc -W
gives an 'empty body' warning.)


If that warning really bugs you, you can insert something like this in
config_h.SH or perl.h.

/*
* BLOCK { statements; } ENDBLOCK;
* can be used as a single statement, as in
* if (x) BLOCK { ... } ENDBLOCK; else ...
*
* Trying to select a version that gives no warnings...
*/
#if !(defined(BLOCK) && defined(ENDBLOCK))
# if defined(__GNUC__) && !defined(__STRICT_ANSI__)
# define BLOCK (void)( /* gcc supports ``({ STATEMENTS; })'' */
# define ENDBLOCK )
# else
# if (VOIDFLAGS) && (defined(sun) || defined(__sun__))
# define BLOCK if (1)
# define ENDBLOCK else (void)0
# else
# define BLOCK do
# define ENDBLOCK while (0)
# endif
# endif
#endif

Now hunt down do{...}while(0)'s:

#define XSRETURN_NO BLOCK { XST_mNO(0); XSRETURN(1); } ENDBLOCK
#define XSRETURN_YES BLOCK { XST_mYES(0); XSRETURN(1); } ENDBLOCK


Regards,

Hallvard
Re: XSUB.h warnings/patch [ In reply to ]
In <9512031859.AA29961@poplar027>
On Sun, 3 Dec 1995 12:59:26 -0600
Dean Roehrich <roehrich@cray.com> writes:
>
>This patch moves the return outside the wrapper. My extensions now compile
>quietly (sure, they still work :). Apply over 5.002beta1. (Are the
>wrappers still necessary?)
>
>! #define XSRETURN_NO do { XST_mNO(0); XSRETSTACK(1); } while (0); return
>! #define XSRETURN_YES do { XST_mYES(0); XSRETSTACK(1); } while (0); return

Consider:

if (some_test)
XSRETURN_YES;
else
XSRETURN_NO;

Becomes:

if (some_test)
do { XST_mYES(0); XSRETSTACK(1); } while (0); return
else
do { XST_mNO(0); XSRETSTACK(1); } while (0); return

And you get syntax error on the 'else';
Re: XSUB.h warnings/patch [ In reply to ]
HBF> (A third way: Remove the (void)0, but then gcc -W
HBF> gives an 'empty body' warning.)

PH> ... or, if you miss a semi-colon out by accident, you'll get a really
PH> hard to debug run-time problem:
PH>
PH> MACRO_USING_ABOVE(wibble, wobble)
PH> i_will_not_be_executed();

Wow. Please keep the (void)0.


PH> We had a long debate about this internally. We use do { ... } while
PH> (0), (sanitised; they're made into macros MACRO_START and MACRO_END).

I like the MACRO_* names; BLOCK could be defined to mean too many other
things.


Regards,

Hallvard
Re: XSUB.h warnings/patch [ In reply to ]
HBF> Here is another way than `do { ... } while(0)', which keeps sun4 cc silent:

HBF> if (1) { ... } else (void)0

HBF> That too needs "unnecessary" expressions/statements, which some compiler
HBF> might warn about. So I guess there is no way to make sure there will
HBF> never be a warning. (A third way: Remove the (void)0, but then gcc -W
HBF> gives an 'empty body' warning.)

... or, if you miss a semi-colon out by accident, you'll get a really
hard to debug run-time problem:

MACRO_USING_ABOVE(wibble, wobble)
i_will_not_be_executed();

We had a long debate about this internally. We use do { ... } while
(0), (sanitised; they're made into macros MACRO_START and MACRO_END).

P.