3

I'm just going through perlxstut and I found there newSVnv in EXAMPLE 5 and EXAMPLE 6 but I think that newSVuv should be more appropriate. Curiously newSVnv works too. What's going on?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Hynek -Pichi- Vychodil
  • 26,174
  • 5
  • 52
  • 73

1 Answers1

3

I think it uses NVs (Perl's equivalent of a C double) instead of UVs (normally an unsigned int), because (depending on OS and compilation options), some of the values in a struct statfs might be 64-bit even though Perl is using 32-bit ints. newSVnv works because the C compiler knows how to cast any integer type to a double.

You should be able to replace newSVnv with newSVuv for any member of statfs that will fit in a UV, and have it work just fine. Perl converts between its numeric types automatically as needed.

cjm
  • 61,471
  • 9
  • 126
  • 175
  • So it means that `newSVnv` is considered safer version of `newSVuv` in Perl sense for Perl's automatic conversion? – Hynek -Pichi- Vychodil Sep 28 '10 at 23:07
  • I'm not sure what you mean by "safer". There's no automatic conversion with the `newSV*v` functions (other than that done by the C compiler). If you pass a `long long` to `newSVuv`, then you get whatever happens when your C compiler casts a `long long` to `unsigned int`. A `double` has a greater range than any integer type, so you don't have to worry about a value that won't fit. – cjm Sep 28 '10 at 23:38
  • that is incorrect; many systems have 8 byte doubles (with 53 bites of precision) and 8 byte integers. storing them in a double can lose precision. – ysth Sep 29 '10 at 02:05
  • @ysth, that's why I said "range" and not "precision". You might lose precision when converting a large integer type to a `double`, but it won't be out of range. – cjm Sep 29 '10 at 02:21