[Rd] incorrect output and segfaults from sprintf with %*d (PR#13667)

Waclaw.Marcin.Kusnierczyk at idi.ntnu.no Waclaw.Marcin.Kusnierczyk at idi.ntnu.no
Mon Apr 27 21:15:27 CEST 2009

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.


More information about the R-devel mailing list