From Waclaw.Marcin.Kusnierczyk at idi.ntnu.no  Mon Apr 27 21:15:27 2009
From: Waclaw.Marcin.Kusnierczyk at idi.ntnu.no (Waclaw.Marcin.Kusnierczyk at idi.ntnu.no)
Date: Mon, 27 Apr 2009 21:15:27 +0200 (CEST)
Subject: [Rd] incorrect output and segfaults from sprintf with %*d
	(PR#13667)
Message-ID: <20090427191527.77109282BE84@mail.pubhealth.ku.dk>

Martin Maechler wrote:
>
>     vQ>     sptinf('%q%s', 1)
>
>
>     vQ> still suggests that one uses %{f,e,g,a} for numerics,
>     vQ> while %s is pretty much valid, too.  you see, in c
>     vQ> sprintf(buffer, "%s", 1) is destined to cause a
>     vQ> segfault, but in r it works -- so the error message is
>     vQ> slightly misleading, as it suggests %s is *not* valid
>     vQ> for numerics.
>
> yes, but only the error message somewhat suggests that;
> at the moment, I'd like to keep it, since really the user
> *should* think of using the number formats, rather than %s
> {which just calls  as.character(.)}  for numeric arguments
>   

then maybe sprintf('%s', 1) should complain about a format-argument
mismatch?  in c, 1 would be taken to be an address at which a string
starts, but in r you do not have pointers, so this interpretation is
impossible.  if the user *should* use number formats for numerics, %s
should not work.  smells lack of design.


>   MM> I think we should signal an error if there are too many arguments.
>
>   vQ> agree.  but it might be more complex than it appears:
>
>     vQ>     sprintf('%3$s', 1, 2, 3)
>
>     vQ> should *not* complain about too many args, despite just
>     vQ> one conversion spec in the format.  
>
> very good point; thanks!
>
>     vQ> Interestingly,
>
>     vQ>     sprintf('%3$s', , , 3) # error: argument is missing,
>     vQ> with no default
>
> yes, empty (aka "missing") arguments are not allowed in  sprintf().
>   

be nice and document such items, pliz....  even if all internal
functions have this behavour (do they?), ?sprintf does not say that
sprintf is internal, or that the r wrapper calls an internal so that all
arguments are necessarily evaluated.

>     >> Could anyone think of a case where the current behavior
>     >> is desirable ?
>     >> 
>
>     vQ> well, one scenario might be that one wants to print a collection of
>     vQ> items with an arbitrary format, supplied by the users,
>     vQ> e.g.
>
>     vQ>     foo = function(fmt) { a = ...  b = ...  ...  s =
>     vQ> sprintf(fmt, a, b, ...)  ... }
>
>     vQ> without having to examine the format to establish which
>     vQ> values are needed.  in the current state, sprintf would
>     vQ> use those it would need to use with a particular format,
>     vQ> with no undesirable complaints.
>
> ok. you have given good examples which make me revert my
> proposal, i.e. continue to not erroring about "too many" arguments. 
>   

i did not say i supported that view, however.  it was just an example
where *a* developer might wish sprintf did not complain about wrong
number of arguments.  examples to the opposite effect can easily be
given, but that's not what you asked about.


>     >>> but they *are* evaluated nevertheless, e.g.:
>     >>> 
>     >>> sprintf('%d', 0, {print(1)}) # "1" # [1] "0"
>     >>> 
>     >>> it might be a good idea to document this behaviour.
>
>    MM> actually I think it should be changed to be more strict
>    MM> (see above).
>
> as a matter of fact, and the result of many more examples,
> I've changed my oppinion and now agree with your original
> proposal:
>
> I've just commmited another sprintf() patch which (among more
> more important changes) *documents* that all arguments of
> sprintf() are evaluated; this actually already entails that
> empty / missing arguments are not allowed.
>   

excellent, thanks.

vQ



[Rd] incorrect output and segfaults from sprintf with %*d (PR#13667)
Waclaw.Marcin.Kusnierczyk at idi.ntnu.no