Summary: you're using h and l incorrectly, as they are meant to edit integers. The fact that they worked in 5.6.1 probably was a mistake in the first place, and the fix didn't show up in perldelta. Support for q was probably eliminated a while back and no one remembered to update the docs (though it could also be that the docs represent some changes that were never made).

First, let me show you the results of your code in 5.8.0 with warnings enabled:

3.1416 Invalid conversion in printf: "%f" at - line 3. %4.4lf Invalid conversion in printf: "%f" at - line 4. %4.4hf Invalid conversion in printf: "%q" at - line 5. %4.4qf 3.1416 3.1416
The relevant part of the perldocs follows:
For numeric conversions, you can specify the size to interpret the number as using l, h, V, q, L or ll. For integer conversions, numbers are usually assumed to be whatever the default integer size is on your platform (usually 32 or 64 bits), but you can override this to use instead one of the standard C types, as supported by the compiler used to build Perl:
l interpret integer as C type "long" or "unsigned long" h interpret integer as C type "short" or "unsigned short" q, L or ll interpret integer as C type "long long" or "unsigned lo +ng long" (if your platform supports such a type, else it is an e +rror)
For floating point conversions, numbers are usually assumed to be the default floating point size on your platform (double or long double), but you can force 'long double' with q, L, or ll if your platform supports them.
Source: perldoc -f sprintf, perl 5.8.0

Now, even according to this, the l and h formats only apply to integers and never floats. So, Perl just warns you and then does what it prints what it can make sense of (the literal string). According to these docs, however, q should not be producing an error.

Next source is the best ANSI C description I could find:
The optional character h, specifying that a following d, i, o, u, x, or X conversion corresponds to a short int or unsigned short int argument, or that a following n conversion corresponds to a pointer to a short int argument.

The optional character l (ell) specifying that a following d, i, o, u, x, or X conversion applies to a pointer to a long int or unsigned long int argument, or that a following n conversion corresponds to a pointer to a long int argument.

The character L specifying that a following e, E, f, g, or G conversion corresponds to a long double argument.

Source: http://www.introl.com/introl-demo/Libraries/C/ANSI_C/stdio/fprintf.html

Again, h and l only are for integers, and in this case q and ll don't even exist. These are also the flags that Visual C++ understands, in addition to I64. Of course, Perl is much more than ANSI C, as the previous docs indicated.

So, let's go to the likely inspiration for Perl's s/printf, the GNU C library:

h A following integer conversion corresponds to a short int or unsigned short int argument, or a fol­ lowing n conversion corresponds to a pointer to a short int argument. l (ell) A following integer conversion corresponds to a long int or unsigned long int argument, or a fol­ lowing n conversion corresponds to a pointer to a long int argument, or a following c conversion cor­ responds to a wint_t argument, or a following s conversion corresponds to a pointer to wchar_t argument. ll (ell-ell). A following integer conversion corre­ sponds to a long long int or unsigned long long int argument, or a following n conversion corresponds to a pointer to a long long int argument. L A following a, A, e, E, f, F, g, or G conversion corresponds to a long double argument. (C99 allows %LF, but SUSv2 does not.) q (`quad'. BSD 4.4 and Linux libc5 only. Don't use.) This is a synonym for ll.
Source: http://www.cgi101.com/class/ch16/envman.cgi?sprintf

For one thing, it looks like ll is also an integer only conversion, but Perl lets it slide as a synonym for L. However, q, which is a synonym for ll, doesn't even work on integers. The manpage says we shouldn't use it, it looks like Perl has decided we shouldn't use it, but no one has updated the perldocs to show this.

Two comments: One can argue how Perl should handle incorrect parameters, but I think the current warning is probably sufficient. Also, I'm not quite sure why ll decided to start working on non-ints in 5.8.0, but I still believe it's either the docs being a bit behind or ahead of the times.

Note: in Win32, the tests you performed behave exactly the same, if you're curious.


In reply to Re: printf size flag incompatibility by Ionitor
in thread printf size flag incompatibility by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.