Discussion:
Used only once in Perl 5.10
(too old to reply)
Erland Sommarskog
2008-04-28 22:29:45 UTC
Permalink
I have this piece of code in my XS module:

if (sv = get_sv("Win32::SqlServer::Version", TRUE))
{
char buff[256];
sprintf_s(buff, 256,
"This is Win32::SqlServer, version %s\n\nCopyright (c)
2005-2008 Erland Sommarskog\n",
XS_VERSION);
sv_setnv(sv, atof(XS_VERSION));
sv_setpv(sv, buff);
SvNOK_on(sv);
}

In Perl 5.10 this yields:

Name "Win32::SqlServer::Version" used only once: possible typo at
F:/Perl/AS1002-AMD64/lib/DynaLoader.pm line 224.

Indeed, this variable is not referred elsewhere, but this did not happen in
Perl 5.8.

Is this an incidental or accidental change?

The workaround seems to be to add a reference in the PM module, although
I have not come around to try that yet. Or should I do the above in some
better way?
--
Erland Sommarskog, Stockholm, ***@sommarskog.se
Nicholas Clark
2008-04-28 22:53:40 UTC
Permalink
if (sv = get_sv("Win32::SqlServer::Version", TRUE | GV_ADDMULTI))
Really that should be
if (sv = get_sv("Win32::SqlServer::Version", GV_ADD | GV_ADDMULTI))
The flags to get_sv() were always a bitmask, never a simple TRUE/FALSE, but
until recently the documentation wasn't very good.
Excuse me while I pop out for a little trip in my time machine. The
documentation is still actually wrong. get_sv() and friends all call
gv_fetchpv(), and it has always taken a bitmask, but none of its callers
have made this clear.

Nicholas Clark
Jan Dubois
2008-04-28 23:15:52 UTC
Permalink
Post by Nicholas Clark
if (sv = get_sv("Win32::SqlServer::Version", TRUE | GV_ADDMULTI))
Really that should be
if (sv = get_sv("Win32::SqlServer::Version", GV_ADD | GV_ADDMULTI))
The flags to get_sv() were always a bitmask, never a simple TRUE/FALSE, but
until recently the documentation wasn't very good.
Excuse me while I pop out for a little trip in my time machine. The
documentation is still actually wrong. get_sv() and friends all call
gv_fetchpv(), and it has always taken a bitmask, but none of its callers
have made this clear.
It didn't really matter that much because TRUE and GV_ADD have the same
value (1), but that's obviously not a good thing to rely on. So I guess
this code in perl.c should also be updated to use GV_ADD:

if (PL_minus_a) {
(void) get_av("main::F", TRUE | GV_ADDMULTI);
}

Cheers,
-Jan
Jan Dubois
2008-04-28 22:48:35 UTC
Permalink
Post by Erland Sommarskog
if (sv = get_sv("Win32::SqlServer::Version", TRUE))
{
char buff[256];
sprintf_s(buff, 256,
"This is Win32::SqlServer, version %s\n\nCopyright (c)
2005-2008 Erland Sommarskog\n",
XS_VERSION);
sv_setnv(sv, atof(XS_VERSION));
sv_setpv(sv, buff);
SvNOK_on(sv);
}
Name "Win32::SqlServer::Version" used only once: possible typo at
F:/Perl/AS1002-AMD64/lib/DynaLoader.pm line 224.
Indeed, this variable is not referred elsewhere, but this did not happen in
Perl 5.8.
Is this an incidental or accidental change?
You were always supposed to get the warning; that you got away without
one is a bug. :)
Post by Erland Sommarskog
The workaround seems to be to add a reference in the PM module, although
I have not come around to try that yet. Or should I do the above in some
better way?
Use the GV_ADDMULTI flag:

if (sv = get_sv("Win32::SqlServer::Version", TRUE | GV_ADDMULTI))

Look it up in perlguts.pod:

| =head2 Creating New Variables
|
| To create a new Perl variable with an undef value which can be accessed from
| your Perl script, use the following routines, depending on the variable type.
|
| SV* get_sv("package::varname", TRUE);
| AV* get_av("package::varname", TRUE);
| HV* get_hv("package::varname", TRUE);
|
| Notice the use of TRUE as the second parameter. The new variable can now
| be set, using the routines appropriate to the data type.
|
| There are additional macros whose values may be bitwise OR'ed with the
| C<TRUE> argument to enable certain extra features. Those bits are:
|
| =over
|
| =item GV_ADDMULTI
|
| Marks the variable as multiply defined, thus preventing the:
|
| Name <varname> used only once: possible typo warning.
|
| =item GV_ADDWARN
|
| Issues the warning:
|
| Had to create <varname> unexpectedly
|
| if the variable did not exist before the function was called.
|
| =back

Cheers,
-Jan
Nicholas Clark
2008-04-28 22:50:37 UTC
Permalink
if (sv = get_sv("Win32::SqlServer::Version", TRUE | GV_ADDMULTI))
Really that should be

if (sv = get_sv("Win32::SqlServer::Version", GV_ADD | GV_ADDMULTI))

The flags to get_sv() were always a bitmask, never a simple TRUE/FALSE, but
until recently the documentation wasn't very good.


Nicholas Clark
Erland Sommarskog
2008-04-30 20:32:29 UTC
Permalink
Post by Jan Dubois
You were always supposed to get the warning; that you got away without
one is a bug. :)
Alright!
Post by Jan Dubois
if (sv = get_sv("Win32::SqlServer::Version", TRUE | GV_ADDMULTI))
That did the trick.

Thanks Jan and Nicholas for the information!
--
Erland Sommarskog, Stockholm, ***@sommarskog.se
Loading...