Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

fputs() in XSUB modules broken (on Win32, or always?)

2 views
Skip to first unread message

Ilya Zakharevich

unread,
Dec 10, 2009, 5:55:32 PM12/10/09
to
Am I correct that fputs() in XSUB modules is completely botched? The
hint I get is from
http://www.nntp.perl.org/group/perl.cpan.testers/2009/11/msg6077293.html
which warns on line with
fputs(SvPV_nolen(ret),stdout);
as
Pari.xs(3799) : warning C4133: 'function' : incompatible types -
from 'char *' to 'struct _iobuf *'
Pari.xs(3799) : warning C4133: 'function' : incompatible types -
from 'struct _iobuf *' to 'const char *'

This is from Win32 perl 5.11.1; I can inspect headers on 5.8.8, and I
see in XSUB.h
# define fputs PerlSIO_fputs
and in iperlsys.h
#define PerlSIO_fputs(f,s) fputs(s,f)

It looks like in one of these definitions there arguments are
exchanged.

So: in which situations is this bug triggered? (This depends on which
define is botched, and I can't easily deduce a way to decide...)

Thanks,
Ilya

sisyphus

unread,
Dec 11, 2009, 2:29:38 AM12/11/09
to
On Dec 11, 9:55 am, Ilya Zakharevich <nospam-ab...@ilyaz.org> wrote:
> Am I correct that fputs() in XSUB modules is completely botched?  The
> hint I get is from
>  http://www.nntp.perl.org/group/perl.cpan.testers/2009/11/msg6077293.html
> which warns on line with
>           fputs(SvPV_nolen(ret),stdout);
> as
>      Pari.xs(3799) : warning C4133: 'function' : incompatible types -
>                              from 'char *' to 'struct _iobuf *'
>      Pari.xs(3799) : warning C4133: 'function' : incompatible types -
>                              from 'struct _iobuf *' to 'const char *'

I get a different warning from attemting to use fputs() like that (in
an Inline::C script):

try_pl_ac08.xs: In function `bar':
try_pl_ac08.xs:11: warning: passing arg 2 of pointer to function from
incompatible pointer type
try_pl_ac08.xs:11: warning: passing arg 3 of pointer to function from
incompatible pointer type

I'm running win32 and it's the same warning with 5.8.9, 5.10.1 and
5.11.2.
That particular construct doesn't prevent the code from compiling, but
causes a crash if an attempt is made to execute it.

If we follow 'perldoc perlclib' recommendations, we would replace that
troublesome line of code with:

PerlIO_puts(PerlIO_stdout(), SvPV_nolen(ret));

And that works fine for me.

Here's the actual script I ran:
##############################
use warnings;

use Inline C => Config =>
BUILD_NOISY => 1;

use Inline C => <<'EOC';

void foo(SV * x) {
PerlIO_puts(PerlIO_stdout(), SvPV_nolen(x));
}

void bar(SV * x) {
fputs(SvPV_nolen(x), stdout);
}

EOC

foo("Hello World\n"); # prints "Hello World\n"
# bar("Hello World\n"); # crashes on win32
##############################

On linux with 5.10.1, the script compiles without any warnings being
issued, and both fputs() and perlIO_puts() work fine.

I don't know if any of this is of any help to you :-)

Cheers,
Rob

Ilya Zakharevich

unread,
Dec 11, 2009, 11:38:30 AM12/11/09
to
On 2009-12-11, sisyphus <sisyp...@gmail.com> wrote:
>> Am I correct that fputs() in XSUB modules is completely botched? �The
>> hint I get is from
>> �http://www.nntp.perl.org/group/perl.cpan.testers/2009/11/msg6077293.html
>> which warns on line with
>> � � � � � fputs(SvPV_nolen(ret),stdout);
>> as
>> � � �Pari.xs(3799) : warning C4133: 'function' : incompatible types -
>> � � � � � � � � � � � � � � �from 'char *' to 'struct _iobuf *'
>> � � �Pari.xs(3799) : warning C4133: 'function' : incompatible types -
>> � � � � � � � � � � � � � � �from 'struct _iobuf *' to 'const char *'

> I'm running win32 and it's the same warning with 5.8.9, 5.10.1 and


> 5.11.2.
> That particular construct doesn't prevent the code from compiling, but
> causes a crash if an attempt is made to execute it.

...


> I don't know if any of this is of any help to you :-)

Is it possible to extract something like output of `gcc -E -dD'
easily? So that one can see which macros are actually enabled on
Win32, so one can try to work around this... (I think this module
works with Perls older than PerlIO...)

Thanks,
Ilya

sisyphus

unread,
Dec 11, 2009, 7:05:10 PM12/11/09
to
On Dec 12, 3:38 am, Ilya Zakharevich <nospam-ab...@ilyaz.org> wrote:

> Is it possible to extract something like output of `gcc -E -dD'
> easily?  So that one can see which macros are actually enabled on
> Win32, so one can try to work around this...  (I think this module
> works with Perls older than PerlIO...)

With Inline::C (assuming that gcc is available), I think it's just a
matter of altering the Config options in the script:

use Inline C => Config =>

CC => 'gcc -E -dD',
BUILD_NOISY => 1;

I find that produces fairly extensive output, so you'll probably want
to redirect stdout and stderr to a file.

On win32 (perl 5.8.9), searching through that output for pre-processor
directives that include the string 'puts', I find

#define PerlSIO_fputs(f,s) (*PL_StdIO->pPuts)(PL_StdIO, (f),(s))
#define fputs PerlSIO_fputs

If you're interested in 'gcc -E -dD' while building a module, I guess
(untested) that you can start with 'perl Makefile.PL CC="gcc -E -dD"'
and then redirect the 'make' output to a file.

Cheers,
Rob

Ilya Zakharevich

unread,
Dec 11, 2009, 10:11:41 PM12/11/09
to
On 2009-12-12, sisyphus <sisyp...@gmail.com> wrote:
> use Inline C => Config =>
> CC => 'gcc -E -dD',
> BUILD_NOISY => 1;
>
> I find that produces fairly extensive output, so you'll probably want
> to redirect stdout and stderr to a file.

> On win32 (perl 5.8.9), searching through that output for pre-processor
> directives that include the string 'puts', I find
>
> #define PerlSIO_fputs(f,s) (*PL_StdIO->pPuts)(PL_StdIO, (f),(s))
> #define fputs PerlSIO_fputs

Thanks. I could not find the slot initializing pPuts slot anywhere;
but judging by other similar code, the first define is correct; hence
the second one must be wrong...

> If you're interested in 'gcc -E -dD' while building a module, I guess
> (untested) that you can start with 'perl Makefile.PL CC="gcc -E -dD"'
> and then redirect the 'make' output to a file.

Never knew about CC= doing anything; myself, I would try OPTIMIZE="-E -dD"...

Thanks again,
Ilya

0 new messages