[2018-11-04 16:21] markus schnalke <mei...@marmaro.de>
> part       text/plain                4116
> Hoi.
Hello;
 
> [2018-11-04 15:32] c_14 <g...@c-14.de>
> > [2018-11-04 14:33] markus schnalke <mei...@marmaro.de>
> >  
> > [..]
> > > part 2     text/x-diff               1523 format_size.patch               
> > >     
> > > diff --git a/uip/mhlistsbr.c b/uip/mhlistsbr.c
> > > index dd6264b..8d4799c 100644
> > > --- a/uip/mhlistsbr.c
> > > +++ b/uip/mhlistsbr.c
> > > @@ -53,6 +53,27 @@ static int list_encoding(CT);
> > >  #define LSTFMT2d2  "\t     %-65.65s\n"
> > >  
> > >  
> > > +char *
> > > +format_size(long unsigned int size)
> > > +{
> > > + static char ret[BUFSIZ];
> > > + char *cp;
> > > +
> > > + /* find correct scale for size (Kilo/Mega/Giga/Tera) */
> > > + for (cp = " KMGT"; size > 9999; size /= 1024) {
> > > +         if (!*++cp) {
> > > +                 return "huge";
> > > +         }
> > > + }
> > > + if (*cp == ' ') {
> > > +         snprintf(ret, sizeof(ret), "%5lu", size);
> > > + } else {
> > > +         snprintf(ret, sizeof(ret), "%4lu%c", size, *cp);
> > > + }
> > > + return ret;
> > > +}
> > 
> > Please don't ever return an array you allocated on the stack in a
> > function. As soon as the function returns, any references to the array
> > become invalid and all accesses to that array become undefined behavior.
> > Although accessing the array and elements thereof might still work on
> > certain systems with certain compilers at certain optimization levels,
> > relying on this behavior is foolhardy at best (this exact issue has
> > already caused problems, see e.g. commit 5edd0). Please either allocate a
> > char* on the heap, or if you really want to keep it on the stack create
> > the array on the stack in the parent function and pass a pointer to the
> > array to format_size. (Note that both of these solutions will preclude
> > your ability to `return "huge";' which would need to be replaced with a
> > call to copy that string into the array/char * in either case.)
> 
> Thanks a lot for the comment. The big problem, as in the mentioned
> commit, is not existent here, as far as I can tell, because the
> array, to which I return a pointer is *static*. It produces defined
> behavior. You probably missed the keyword `static'.
Yeah, I missed that in my first read-through, I also completely forgot
about static for functions even though I should know better. Guess I
wasn't as awake as I thought I was.
 
> The only technical problem here, is that there is only one return
> space for the function, thus each further function call overwrites
> the previous result. If you want to save it, you have to copy the
> result. (See the manpage of strtok(3) for a standard example of
> this scheme. Or grep for /^.static/ in sbr/* for more mmh examples.)
> 
> Nonetheless, I agree that this approach might not be the best in
> this case. I'm not yet sure. The advantage is that it creates the
> least overhead. The disadvantage is that we cannot do:
> 
>       printf("%s %s\n", format_size(x), format_size(y));
> 
> But if we don't want to do that, but still use this function
> primarily for outputting (which I assume is the case), then the
> static result space inside the function might be the best way to
> go.
I did just try and think of other possible solutions, such as replacing
the format_size function with a printf-wrapper that instead of returning
a char* prints the formatted size directly, but all the solutions I came
up with were either less flexible than your approach or much more
complicated. Your solution is probably the best for ease-of-use and
minimal code complexity. Maybe just add a comment above the format_size
function stating that you can't call the function twice in a single
printf() because subsequent calls will overwrite data returned by the
first call to the function? (Just in case somebody in future also
doesn't notice the static)

[..]
> Am I missing something out?
Nothing I can see right now anyways.

> To be clear: I am hugely thankful that you had a look at the patch.
> Explaining that much and ``thinking myself through the topic'' is
> my way of checking it. Doing that by email forces me to not take
> shortcuts in my thoughts.
Yeah, no problem. I really should have been paying more attention
anyways.

-- 
c_14

Reply via email to