Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.92k stars 550 forks source link

%zd format in printf #10864

Closed p5pRT closed 13 years ago

p5pRT commented 13 years ago

Migrated from rt.perl.org#79956 (status was 'resolved')

Searchable as RT79956$

p5pRT commented 13 years ago

From @epa

Created by @epa

The system C library printf() on this system supports a 'z' format modifier​:

  z A following integer conversion corresponds to a size_t or   ssize_t argument.

So in C you can say

  size_t x = sizeof(int); printf("%zd"\, x);

This is useful because a size_t might not fit into an int\, so using plain %d is not right.

As wishlist items could I ask about a few things​:

- Please consider adding support for this z format modifier. In perl you   don't have size_t or integer overflow\, but it would not hurt to allow it   to help porting C code.

- If an unrecognized format string is used\, shouldn't printf() give a warning?

- In XS code\, it would be useful for newSVpvf() to support it.   And again if XS code uses an unrecognized format character should this   not produce a warning?

Perl Info ``` Flags: category=core severity=wishlist This perlbug was built using Perl 5.10.0 in the Fedora build system. It is being executed now by Perl 5.10.0 - Tue Oct 12 16:07:05 UTC 2010. Site configuration information for perl 5.10.0: Configured by Red Hat, Inc. at Tue Oct 12 16:07:05 UTC 2010. Summary of my perl5 (revision 5 version 10 subversion 0) configuration: Platform: osname=linux, osvers=2.6.32-72.el6.bz634452.x86_64, archname=x86_64-linux-thread-multi uname='linux x86-05.phx2.fedoraproject.org 2.6.32-72.el6.bz634452.x86_64 #1 smp fri sep 17 06:52:25 edt 2010 x86_64 x86_64 x86_64 gnulinux ' config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Accflags=-DPERL_USE_SAFE_PUTENV -Dccdlflags=-Wl,--enable-new-dtags -Dversion=5.10.0 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dprivlib=/usr/lib/perl5/5.10.0 -Dsitelib=/usr/local/lib/perl5/site_perl/5.10.0 -Dvendorlib=/usr/lib/perl5/vendor_perl/5.10.0 -Darchlib=/usr/lib64/perl5/5.10.0/x86_64-linux-thread-multi -Dsitearch=/usr/local/lib64/perl5/site_perl/5.10.0/x86_64-linux-thread-m ulti -Dvendorarch=/usr/lib64/perl5/vendor_perl/5.10.0/x86_64-linux-thread-mul ti -Dinc_version_list=none -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dotherlibdirs=/usr/lib/perl5/site_perl' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DPERL_USE_SAFE_PUTENV -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm', optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic', cppflags='-D_REENTRANT -D_GNU_SOURCE -DPERL_USE_SAFE_PUTENV -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -I/usr/include/gdbm' ccversion='', gccversion='4.4.4 20100630 (Red Hat 4.4.4-10)', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='gcc', ldflags ='' libpth=/usr/local/lib64 /lib64 /usr/lib64 libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.11.2' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,--enable-new-dtags -Wl,-rpath,/usr/lib64/perl5/5.10.0/x86_64-linux-thread-multi/CORE' cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' Locally applied patches: @INC for perl 5.10.0: /home/eda/lib/perl5/5.10.0 /home/eda/lib/perl5/site_perl/5.10.0 /usr/local/lib64/perl5/site_perl/5.10.0/x86_64-linux-thread-multi /usr/local/lib/perl5/site_perl/5.10.0 /usr/lib64/perl5/vendor_perl/5.10.0/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.10.0 /usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.10.0/x86_64-linux-thread-multi /usr/lib/perl5/5.10.0 /usr/lib/perl5/site_perl/5.10.0 /usr/lib/perl5/site_perl . Environment for perl 5.10.0: HOME=/home/eda LANG=en_GB.UTF-8 LANGUAGE (unset) LC_COLLATE=C LC_CTYPE=en_GB.UTF-8 LC_MESSAGES=en_GB.UTF-8 LC_MONETARY=en_GB.UTF-8 LC_NUMERIC=en_GB.UTF-8 LC_TIME=en_GB.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/eda/bin:/home/eda/bin:/usr/lib64/qt-3.3/bin:/usr/kerberos/sbi n:/usr/kerberos/bin:/usr/lib64/ccache:/usr/local/bin:/bin:/usr/bin:/usr/ local/sbin:/usr/sbin:/sbin:/sbin:/usr/sbin:/home/eda/bin:/sbin:/usr/sbin PERL5LIB=/home/eda/lib/perl5/5.10.0:/home/eda/lib/perl5/site_perl/5.10.0 PERL_BADLANG (unset) SHELL=/bin/bash -- Ed Avis ______________________________________________________________________ This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email ______________________________________________________________________ ```
p5pRT commented 13 years ago

From @ikegami

On Mon\, Nov 29\, 2010 at 11​:00 AM\, Ed Avis \perlbug\-followup@​perl\.org wrote​:

So in C you can say

size_t x = sizeof(int); printf("%zd"\, x);

This is useful because a size_t might not fit into an int\, so using plain %d is not right.

"%d" already covers the full range of numbers Perl stores as native integers.

To cover the full range of integers Perl can store\, use "%.0f".

- If an unrecognized format string is used\, shouldn't printf() give a

warning?

Yes\, and it does (\<\<Invalid conversion in printf​: "%z">>)

- Eric

p5pRT commented 13 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 13 years ago

From @chipdude

On 11/29/2010 11​:36 AM\, Eric Brine wrote​:

On Mon\, Nov 29\, 2010 at 11​:00 AM\, Ed Avis \perlbug\-followup@&#8203;perl\.org wrote​:

So in C you can say

size_t x = sizeof(int); printf("%zd"\, x);

This is useful because a size_t might not fit into an int\, so using plain %d is not right.

"%d" already covers the full range of numbers Perl stores as native integers.

True\, but Perl's printf implementation was designed to be a full simulation of C printf. (I should know\, I wrote it. :-)) Adding 'z' seems like a tiny harmless idea to me.

# perl -e 'printf "%hd\n"\, 1' 1 # perl -e 'printf "%ld\n"\, 1' 1 # perl -e 'printf "%zd\n"\, 1' %zd

p5pRT commented 13 years ago

From @ikegami

On Mon\, Nov 29\, 2010 at 5​:38 PM\, Reverend Chip \rev\.chip@&#8203;gmail\.com wrote​:

On 11/29/2010 11​:36 AM\, Eric Brine wrote​:

On Mon\, Nov 29\, 2010 at 11​:00 AM\, Ed Avis \perlbug\-followup@&#8203;perl\.org wrote​:

So in C you can say

size_t x = sizeof(int); printf("%zd"\, x);

This is useful because a size_t might not fit into an int\, so using plain %d is not right.

"%d" already covers the full range of numbers Perl stores as native integers.

True\, but Perl's printf implementation was designed to be a full simulation of C printf. (I should know\, I wrote it. :-)) Adding 'z' seems like a tiny harmless idea to me.

Wouldn't it be more useful to have a specifier than print any integer Perl supports?

p5pRT commented 13 years ago

From @ikegami

On Mon\, Nov 29\, 2010 at 5​:38 PM\, Reverend Chip \rev\.chip@&#8203;gmail\.com wrote​:

On 11/29/2010 11​:36 AM\, Eric Brine wrote​:

On Mon\, Nov 29\, 2010 at 11​:00 AM\, Ed Avis \perlbug\-followup@&#8203;perl\.org wrote​:

So in C you can say

size_t x = sizeof(int); printf("%zd"\, x);

This is useful because a size_t might not fit into an int\, so using plain %d is not right.

"%d" already covers the full range of numbers Perl stores as native integers.

True\, but Perl's printf implementation was designed to be a full simulation of C printf. (I should know\, I wrote it. :-)) Adding 'z' seems like a tiny harmless idea to me.

If we're gonna start supporting types larger than an IV\, we should start with %lld.

$ perl -e'printf "%lld\n"\, 2**40' %lld

p5pRT commented 13 years ago

From tchrist@perl.com

On 11/29/2010 11​:36 AM\, Eric Brine wrote​:

On Mon\, Nov 29\, 2010 at 11​:00 AM\, Ed Avis \perlbug\-followup@&#8203;perl\.org wrote​:

So in C you can say

size_t x = sizeof(int); printf("%zd"\, x);

This is useful because a size_t might not fit into an int\, so using plain %d is not right.

"%d" already covers the full range of numbers Perl stores as native integers.

True\, but Perl's printf implementation was designed to be a full simulation of C printf. (I should know\, I wrote it. :-)) Adding 'z' seems like a tiny harmless idea to me.

Icky acky ucky.

I *hate* languages that make you pepper your printfs with size bits! %lld this and %lu that and %llf or %ld. No thanks!

--tom

p5pRT commented 13 years ago

From @chipdude

On 11/29/2010 5​:54 PM\, Tom Christiansen wrote​:

I *hate* languages that make you pepper your printfs with size bits! %lld this and %lu that and %llf or %ld. No thanks!

If printf isn't your thing\, feel free to ignore it. But for those who do use it\, a consistent equivalence to C is expected and achievable.

p5pRT commented 13 years ago

From @chipdude

On 11/29/2010 3​:11 PM\, Eric Brine wrote​:

On Mon\, Nov 29\, 2010 at 5​:38 PM\, Reverend Chip \<rev.chip@​gmail.com \mailto&#8203;:rev\.chip@&#8203;gmail\.com> wrote​:

Perl's printf implementation was designed to be a full
simulation of C printf\.  \(I should know\, I wrote it\.  :\-\)\)  Adding 'z'
seems like a tiny harmless idea to me\.

If we're gonna start supporting types larger than an IV\, we should start with %lld.

$ perl -e'printf "%lld\n"\, 2**40' %lld

Nobody said anything about exceeding IV\, though we might already do so with '%qd' anyway. For Perl\, 'z' is just sugar for 'V'\, since IV/UV are effectively guaranteed to be at least 'z' size.

p5pRT commented 13 years ago

From @chipdude

On 11/29/2010 3​:06 PM\, Eric Brine wrote​:

On Mon\, Nov 29\, 2010 at 5​:38 PM\, Reverend Chip \<rev.chip@​gmail.com \mailto&#8203;:rev\.chip@&#8203;gmail\.com> wrote​:

Perl's printf implementation was designed to be a full
simulation of C printf\.  \(I should know\, I wrote it\.  :\-\)\)  Adding 'z'
seems like a tiny harmless idea to me\.

Wouldn't it be more useful to have a specifier than print any integer Perl supports?

That's what %Vd does. Also\, false dilemma.

p5pRT commented 13 years ago

From @ikegami

On Mon\, Nov 29\, 2010 at 10​:45 PM\, Reverend Chip \rev\.chip@&#8203;gmail\.com wrote​:

On 11/29/2010 3​:11 PM\, Eric Brine wrote​:

On Mon\, Nov 29\, 2010 at 5​:38 PM\, Reverend Chip \<rev.chip@​gmail.com \mailto&#8203;:rev\.chip@&#8203;gmail\.com> wrote​:

Perl's printf implementation was designed to be a full
simulation of C printf\.  \(I should know\, I wrote it\.  :\-\)\)  Adding

'z' seems like a tiny harmless idea to me.

If we're gonna start supporting types larger than an IV\, we should start with %lld.

$ perl -e'printf "%lld\n"\, 2**40' %lld

Nobody said anything about exceeding IV\,

He said %d wasn't right\, and %d formats an IV. The value can't be smaller than an IV\, so it must be larger.

Or am I wrong about %d working for IV-sized ints?

- Eric

p5pRT commented 13 years ago

From tchrist@perl.com

On 11/29/2010 5​:54 PM\, Tom Christiansen wrote​:

I *hate* languages that make you pepper your printfs with size bits! %lld this and %lu that and %llf or %ld. No thanks!

If printf isn't your thing\, feel free to ignore it.

It is.

I just see no reason when this works fine on BSD​:

  printf("TIOCGWINSZ %#08x\n"\, TIOCGWINSZ );   printf("sizeof struct winsize %d\n"\, sizeof(struct winsize) );

SysV forces to write this annoyance​:

  printf("TIOCGWINSZ %#08lx\n"\, TIOCGWINSZ );   printf("sizeof struct winsize %lu\n"\, sizeof(struct winsize) );

There's no sense to it -- especially in Perl. Why add things that are meaningless noise?

--tom

p5pRT commented 13 years ago

From @chipdude

On 11/29/2010 9​:49 PM\, Eric Brine wrote​:

On Mon\, Nov 29\, 2010 at 10​:45 PM\, Reverend Chip \<rev.chip@​gmail.com \mailto&#8203;:rev\.chip@&#8203;gmail\.com> wrote​:

On 11/29/2010 3&#8203;:11 PM\, Eric Brine wrote&#8203;:
> On Mon\, Nov 29\, 2010 at 5&#8203;:38 PM\, Reverend Chip
\<rev\.chip@&#8203;gmail\.com \<mailto&#8203;:rev\.chip@&#8203;gmail\.com>
> \<mailto&#8203;:rev\.chip@&#8203;gmail\.com \<mailto&#8203;:rev\.chip@&#8203;gmail\.com>>> wrote&#8203;:
>
>     Perl's printf implementation was designed to be a full
>     simulation of C printf\.  \(I should know\, I wrote it\.  :\-\)\)
 Adding 'z'
>     seems like a tiny harmless idea to me\.
>
>
> If we're gonna start supporting types larger than an IV\, we should
> start with %lld\.
>
> $ perl \-e'printf "%lld\\n"\, 2\*\*40'
> %lld

Nobody said anything about exceeding IV\,

He said %d wasn't right\, and %d formats an IV.... Or am I wrong about %d working for IV-sized ints?

Fraid so. %d formats an int (whatever that is\, locally). Grep for \'d\' in sv.c to find it.

p5pRT commented 13 years ago

From @chipdude

On 11/29/2010 10​:01 PM\, Tom Christiansen wrote​:

On 11/29/2010 5​:54 PM\, Tom Christiansen wrote​:

I *hate* languages that make you pepper your printfs with size bits! %lld this and %lu that and %llf or %ld. No thanks! If printf isn't your thing\, feel free to ignore it. It is.

I just see no reason when this works fine on BSD​:

printf\("TIOCGWINSZ %\#08x\\n"\,            TIOCGWINSZ             \);
printf\("sizeof struct winsize %d\\n"\,    sizeof\(struct winsize\) \);

But of course that doesn't work fine wherever sizeof(int) != sizeof(size_t)\, which is enough places to matter. Not to mention the evil of using %d for an unsigned value\, but no matter\, and I just mentioned it\, bad me.

SysV forces to write this annoyance​:

printf\("TIOCGWINSZ %\#08lx\\n"\,           TIOCGWINSZ             \);
printf\("sizeof struct winsize %lu\\n"\,   sizeof\(struct winsize\) \);

But that\, of course\, is just as wrong\, only it's wrong where sizeof(long) != sizeof(size_t). Which is also enough places to matter. The only right-ish ways to do that are​:

  printf("sizeof struct winsize %zu\n"\, sizeof(struct winsize) ); /* modern with 'z' */   printf("sizeof struct winsize %lu\n"\, (unsigned long)sizeof(struct winsize) ); /* pre-modern */

... and I'm not 100% sure that the latter is safe. It depends on a factoid I don't remember​: whether ISO allows sizeof(size_t) > sizeof(long). I believe it does. In which case you're stuck with either 'z' or a cast to uintmax_t and a printf format that include PRIuMAX and string pasting.

It's an ugly corner of C\, isn't it? But then\, Shirley\, you knew this\, and you've suckered me giving evidence that printf is a swamp that should be drained\, rather than maintained. Sadly\, it was to no avail​:

There's no sense to it -- especially in Perl. Why add things that are meaningless noise?

Adding 'z' merely continues to ensure that Perl's "sprintf" lives up to its name. K&R created printf\, but then ANSI\, ISO\, BSD\, SysV\, Microsoft\, GNU\, etc. all added their fiddly bits. And Perl already implements those fiddly bits\, for hysterical raisins\, because Perl's printf was from the beginning a callout to the local system printf. (Perl even implements Microsoft-specific printf features\, but only on Windows... specifically\, the %I64 and %I32 size prefixes.) I only reimplemented printf for safety reasons\, not to drain the swamp. And while the swamp hasn't been maintained as assiduously as it used to be -- thus\, the case of the missing 'z' -- it's a swamp we can't drain\, lest the alligators escape and eat us in karmic retaliation.

p5pRT commented 13 years ago

From @jandubois

On Tue\, 30 Nov 2010\, Reverend Chip wrote​:

On 11/29/2010 9​:49 PM\, Eric Brine wrote​:

He said %d wasn't right\, and %d formats an IV.... Or am I wrong about %d working for IV-sized ints?

Fraid so. %d formats an int (whatever that is\, locally). Grep for \'d\' in sv.c to find it.

For a call at the C level you are correct\, but at the Perl level the "%d" format is the same as "%Vd"​:

  case 'V'​:   default​: iv = tiv; break;

64-bit Windows is probably the only platform where sizeof(int) \< sizeof(IV)​:

C​:\Perl64-5.12\bin>perl "-V​:(int|iv)size" intsize='4'; ivsize='8'; C​:\Perl64-5.12\bin>perl -e "printf '%d'\, 2**34" 17179869184

Cheers\, -Jan

p5pRT commented 13 years ago

From @jandubois

On Tue\, 30 Nov 2010\, Jan Dubois wrote​:

On Tue\, 30 Nov 2010\, Reverend Chip wrote​:

On 11/29/2010 9​:49 PM\, Eric Brine wrote​:

He said %d wasn't right\, and %d formats an IV.... Or am I wrong about %d working for IV-sized ints?

Fraid so. %d formats an int (whatever that is\, locally). Grep for \'d\' in sv.c to find it.

For a call at the C level you are correct\, but at the Perl level the "%d" format is the same as "%Vd"​:

    case 'V'&#8203;:
    default&#8203;:    iv = tiv; break;

64-bit Windows is probably the only platform where sizeof(int) \< sizeof(IV)​:

Ok\, so that was nonsense\, it is the only platform where sizeof(long) \< sizeof(IV); the relationship above is true for all LP64 platforms too.

But the rest remains true regardless.

Cheers\, -Jan

C​:\Perl64-5.12\bin>perl "-V​:(int|iv)size" intsize='4'; ivsize='8'; C​:\Perl64-5.12\bin>perl -e "printf '%d'\, 2**34" 17179869184

Cheers\, -Jan

p5pRT commented 13 years ago

From @arc

Reverend Chip \rev\.chip@&#8203;gmail\.com wrote​:

printf("sizeof struct winsize %zu\n"\, sizeof(struct winsize) ); /* modern with 'z' */    printf("sizeof struct winsize %lu\n"\,   (unsigned long)sizeof(struct winsize) );  /* pre-modern */

... and I'm not 100% sure that the latter is safe.  It depends on a factoid I don't remember​: whether ISO allows sizeof(size_t) > sizeof(long).  I believe it does.

C99 allows sizeof(size_t) > sizeof(long)\, but C89 doesn't. So that second line is maximally portable according to C89\, but C99 permits LLP64 implementations (for example) to break it.

-- Aaron Crane ** http​://aaroncrane.co.uk/

p5pRT commented 13 years ago

From @chipdude

On 11/30/2010 12​:37 AM\, Jan Dubois wrote​:

On Tue\, 30 Nov 2010\, Jan Dubois wrote​:

On Tue\, 30 Nov 2010\, Reverend Chip wrote​:

On 11/29/2010 9​:49 PM\, Eric Brine wrote​:

He said %d wasn't right\, and %d formats an IV.... Or am I wrong about %d working for IV-sized ints? Fraid so. %d formats an int (whatever that is\, locally). Grep for \'d\' in sv.c to find it. For a call at the C level you are correct\, but at the Perl level the "%d" format is the same as "%Vd"​: case 'V'​: default​: iv = tiv; break;

Ah\, quite so; missed that\, thanks.

p5pRT commented 13 years ago

From jpl@research.att.com

Quoth Reverend Chip

On 11/29/2010 3​:06 PM\, Eric Brine wrote​:

On Mon\, Nov 29\, 2010 at 5​:38 PM\, Reverend Chip \<rev.chip@​gmail.com \mailto&#8203;:rev\.chip@&#8203;gmail\.com> wrote​:

Perl's printf implementation was designed to be a full
simulation of C printf\.  \(I should know\, I wrote it\.  :\-\)\)  Adding 'z'
seems like a tiny harmless idea to me\.

Wouldn't it be more useful to have a specifier than print any integer Perl supports?

That's what %Vd does. Also\, false dilemma.

In case the water isn't muddy enough\, consider those\, such as I\, writing XS extensions. I always try to implement the nitty-gritty routines in pure C\, so they can be incorporated into a pure C library\, or into P*th*n\, etc. Software reuse. It also makes it a ton easier to find all my memory leaks and causes of core dumps\, which can be elusive in the perl test environment. So I don't want to rely on some feature that works only in perl.

I share Tom Christiansen's gag response at all the stuff that has crept into printf formats\, but I'm resigned to it.

=== Ancient history section (feel free to ignore)

My one and only contribution to ANSI C was the concept that adjacent string literals be combined to act like the concatenation of those literals. This was motivated by being forced to work on a telephone company switch pretending to be a computer. It lacked\, among other things\, floating point. I had numerous awk scripts that didn't need anything fancier than ints\, so I recompiled awk with something like

typedef AWKFLOAT int; /* int instead of double */

and it *almost* worked. But I also had to change a handful of %g format items to anticipate ints. After which\, it worked perfectly. But the changes would have been easier if I could have done something like

#define AWKFLOATFMT "%g"

and then replaced "%g\n" (or whatever) with AWKFLOATFMT "\n". And the ANSI C folks were kind enough to make that work (long after I was liberated from programming on the switch).

It would be nice if there were a way to associate format items with assorted typedef-ed base types\, but I doubt that will happen in C. A good second-best might be a format character and cast so that the format character would properly deal with anything cast to the corresponding gizmo. -- jpl

p5pRT commented 13 years ago

From @epa

Eric Brine \<ikegami \ adaelis.com> writes​:

So in C you can say

size_t x = sizeof(int); printf("%zd"\, x);

This is useful because a size_t might not fit into an int\, so using plain %d is not right.

"%d" already covers the full range of numbers Perl stores as native integers.

Right. In Perl. But in C a size_t might not fit into a %d. That is why C's printf() function (on some systems at least) supports %zd.

Since Perl's printf() is an imitation of C's one (I am old enough to remember the days when it just called through to the C library) it ought to support the same stuff\, for least surprise.

- If an unrecognized format string is used\, shouldn't printf() give a warning?

Yes\, and it does (\<\<Invalid conversion in printf​: "%z">>)

Duh\, when writing my test program I forgot to turn on warnings. Sorry :-p.

-- Ed Avis \eda@&#8203;waniasset\.com

p5pRT commented 13 years ago

From @demerphq

On 30 November 2010 07​:01\, Tom Christiansen \tchrist@&#8203;perl\.com wrote​:

On 11/29/2010 5​:54 PM\, Tom Christiansen wrote​:

I *hate* languages that make you pepper your printfs with size bits! %lld this and %lu that and %llf or %ld.  No thanks!

If printf isn't your thing\, feel free to ignore it.

It is.

I just see no reason when this works fine on BSD​:

   printf("TIOCGWINSZ %#08x\n"\,            TIOCGWINSZ             );    printf("sizeof struct winsize %d\n"\,    sizeof(struct winsize) );

SysV forces to write this annoyance​:

   printf("TIOCGWINSZ %#08lx\n"\,           TIOCGWINSZ             );    printf("sizeof struct winsize %lu\n"\,   sizeof(struct winsize) );

There's no sense to it -- especially in Perl.  Why add things that are meaningless noise?

If its a meaningless flag\, but allows stuff to ported more easily then why not?

cheers\, Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From tchrist@perl.com

If its a meaningless flag\, but allows stuff to ported more easily then why not?

Isn't that the idea that got us all of \g{NAME} *and* \k'NAME' *and* \k\ *and* (?P=NAME)?

Was that really a win?

--tom

PS​: Did I miss any? :(

p5pRT commented 13 years ago

From @chipdude

On 11/30/2010 6​:53 AM\, John P. Linderman wrote​:

I share Tom Christiansen's gag response at all the stuff that has crept into printf formats\, but I'm resigned to it.

Indeed.

[when writing XS] I don't want to rely on some feature that works only in perl.

Nice point there; adding 'z' is worthwhile if only for that. Good thing we have string pasting as a workaround. Speaking of which​:

=== Ancient history section (feel free to ignore)

My one and only contribution to ANSI C was the concept that adjacent string literals be combined to act like the concatenation of those literals.

Hey\, thanks. That was a great little idea - it's enabled some nice hackery.

It would be nice if there were a way to associate format items with assorted typedef-ed base types\, but I doubt that will happen in C.

Well the C99 PRIxYYY obviously reaches in that direction\, but can't get there. What's really needed is a self-describing stdarg list. Then all you'd need is {1} {2} etc. a la C#. Library devs could have a lot of fun with that.

p5pRT commented 13 years ago

From @demerphq

On 30 November 2010 18​:04\, Tom Christiansen \tchrist@&#8203;perl\.com wrote​:

If its a meaningless flag\, but allows stuff to ported more easily then why not?

Isn't that the idea that got us all of \g{NAME} *and* \k'NAME' *and* \k\ *and* (?P=NAME)?

Was that really a win?

Yes. If it makes it easier to port Python\, Java and .Net scripts to perl\, and means that examples from MRE work in Perl then I think it was.

We have an ecosystem here. It keeps food on peoples tables.

If we dont support the ecosystem and let it die then eventually those tables will be bare. Or we will be writing in some horrible other language.

So if adding a few redundancies encourages people to write more perl code\, meaning more perl devs have nice contracts\, well then I personally feel it is a BIG win.

OTOH\, we *didnt * copy the *really* stupid parts from any of those other places.... I'm not that crazy!

--tom

PS​: Did I miss any? :(

Depends on your point of view. You could also include numeric capture buffers.

Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From tchrist@perl.com

Fine.

p5pRT commented 13 years ago

From @cpansprout

This feature was added in commit 07208e09.

p5pRT commented 13 years ago

@cpansprout - Status changed from 'open' to 'resolved'