printf bad ?

Tim Writer tim-s/rLXaiAEBtBDgjK7y7TUQ at public.gmane.org
Sat Mar 19 16:26:11 UTC 2005


Peter <plp-ysDPMY98cNQDDBjDh4tngg at public.gmane.org> writes:

> On Fri, 18 Mar 2005, John Macdonald wrote:
> 
> > As far as bash is concerned, the argument to printf is just
> > a bunch of characters, not a string.  Imagine a program
> > addinventory that takes an incoming shipment and adds it to
> > the amount of inventory on hand - with pairs of arguments that
> > are part-key and quantity-received.
> >
> > addinventory x3y2 24
> > addinventory 0z99 144
> > addinventory 0x33 75
> >
> > You wouldn't want bash to change the part key on the last
> > command to 51 because bash decided to treat it as a number?
> 
> No, but I'd expect the command line to be sane decimal number-wise (2005
> style, not 1970s style). So I'd expect 0012 to be evaluated as 12 decimal not
> 10 decimal in *any* number context and that behavior to be consistent, or at
> least 10#0012 to be decimal in any numeric context (for example, when
> bash::printf is converting an argument for a %d option).

You're talking about the principle of least surprise which, IMO, dictates
that bash printf behaves like /usr/bin/printf which, in turn, behaves like
C's printf() (not to menion awk's printf, Perl's printf, etc.).  Anything
else would be inconsistent and lead to bugs.

> Especially when
> handling directory structures as often used with databases, mail systems etc
> (directories 00,01,02 ...). All is well until one writes a script to iterate
> over them numerically by incrementing the 'name' as a number, when it is
> already formatted, and then reach 00008, and oops, we have a problem.

The easiest way to do that is to use zsh:

    for file in <0->; do
        something $file
    done

which iterates over all numerically named files.

Of course, files are commonly named with leading zeros to force numeric order
and alphabetic order to be the same, so these examples seem contrived as you
can just iterate like this:

    for file in *; do
        something $file
    done

> Or
> execve a program written in C with a filename of the form 00012 as argument,
> convert it using strtoul in the hope of being able to iterate over more files
> like it (like 00013, 00014 ...), and end up with unexpected results. Lesson:
> *always* step past leading zeros in a number to be converted with
> strtoul(_,_,0) unless expecting octal input base.

Unless decimal is part of the specification, how do you know the files aren't
named in octal sequence?  Database applications like this shouldn't be
written to do the most likely (but possibly incorrect) thing, they should be
written to do the correct thing.  IOW, if you want to iterate through the
files in decimal sequence, say so and write:

    strtoul(_, _, 10)

[snip]

> > Why would 008 be decimal and not base 9?  Is 0101 binary
> > or octal?
> 
> Normal people assume that the default base for numbers on the command line is
> the one they use everyday. With or without leading zeros. By this I do not
> mean sysadmins and programmers, but average users who know 10 commands and
> don't want to learn more (not my case but this is the idea).

There is no default base for numbers on the command line as the command line
(or rather bash in this case) deals only with strings unless explicitly
provided a numeric context like:

    $(( ))

Besides, users who know 10 commands and don't want to learn more are unlikely
to need or want printf.  If you're using printf, you're programming, at which
point you'd be well advised to learn something about your tools.  Doctors,
carpenters, dentists, plumbers, machinists, etc. learn how to use their tools
before jumping in at the deep end.  Why should programmers (even casual or
hobbyist programmers) be any different?  If you're not interested in learning
how to use the tools properly and if you're unwilling to learn why things
work the way they do, you're not going to enjoy programming.  Life is short,
find something more interesting to do with your time.

> > If you guess the base from which digits are used, there are
> > lots of numbers in that base that can't be written because
> > they happen to only use small digits.
> 
> I agree. But when set to automatically detect the base then the program
> *should* try a number in the default *user* number base first (as opposed to
> the system default, octal), then try the rest. At least that's my opinion. By
> program I mean most shell commands meant to be used by users. I realise that
> this would break the usual use of chmod but that could be made an
> exception. It's just an opinion.

Again, there's no default user base and no system default.  Many programs
operate in decimal as the norm, many (most?) programming languages use the
conventions described herein, other applications use something altogether
different.  There is no convention that makes sense for all programs all the
time.  In general, programmers choose a "reasonable" convention for the
particular problem domain.

[snip]

> Can you quote one application, excepting chmod, where octal use on the
> command line is common ?

printf ;-)

[snip]

-- 
tim writer <tim-s/rLXaiAEBtBDgjK7y7TUQ at public.gmane.org>                                  starnix inc.
647.722.5301                                      toronto, ontario, canada
http://www.starnix.com              professional linux services & products
--
The Toronto Linux Users Group.      Meetings: http://tlug.ss.org
TLUG requests: Linux topics, No HTML, wrap text below 80 columns
How to UNSUBSCRIBE: http://tlug.ss.org/subscribe.shtml





More information about the Legacy mailing list