News for hackers. Stuff that matters.
Re:Comparing the Cost of Different Multiple-return Technique... by acqq on Monday December 23, 2013 @01:18PM (#6955641)
I don't see the description of the most obvious (to this old C programmer) approach: if your function "returns multiple values" it probably should be rewritten to operate on a struct. Once you recognize that, you'd probably discover that you'll be able to use the same struct in more other functions, and that you'd need just to pass a single pointer to that stuct around, significantly reducing the overhead of a lot of parameter passing.
Re:Comparing the Cost of Different Multiple-return Technique... by dmlorenzetti on Monday December 23, 2013 @01:24PM (#6955679)
One of the methods tested was mutate-struct -- Dereference a struct pointer and mutate both its fields.
Re:Comparing the Cost of Different Multiple-return Technique... by acqq on Monday December 23, 2013 @01:29PM (#6955706)
Thanks. I haven't seen the description under "Three Common Techniques." And I also claim that the benchmarking isn't giving the method the due justice as the benefits of it can be visible only in the context where you really do operate with more functions on the same structures. Moreover, I think it's better to simply know how the C is translated to the assembly then to measure one very limited example. Specifically, some optimizations avoid calling functions at all. But the measurements of such examples don't properly reflect the behavior in bigger programs, where it can be bigger performance benefit to have smaller code than a fast microbenchmark.
Re:Comparing the Cost of Different Multiple-return Technique... by Arnor on Monday December 23, 2013 @05:56PM (#6957145)
I tend to agree with this approach and use it myself (in the rare instances that I use C). My only complaint is that as the number of functions touching the struct grow, maintainability gets harder. Can you share any rules/strategies to mitigate this problem?
Re:Comparing the Cost of Different Multiple-return Technique... by yoklov on Tuesday December 24, 2013 @12:50AM (#6958423)
You basically split it up in a similar way that you'd use in an OO language, except you don't have inheritance and only have composition. Specifically, you break apart the logically distinct portions of your structs and you make them structs themselves. E.g. compare (trivial examples, but you get the idea).

    /* okay */
    struct monster {
      unsigned id;
      int x, y, hp;
      /* etc. */
    };
    /* better */
    struct point { int x, y; };
    struct monster {
      unsigned id;
      struct point pos;
      int hp;
    };
This also allows a form of inheritance. For example if you have

    struct bad_monster {
      struct monster base;
      int badness; /* your imagination is the limit. */
    };

    /* this is safe */
    struct bad_monster bad;
    struct monster *some_monster = (struct monster *)&bad; /* equivalently &bad.base */
    some_function_expecting_a_monster(some_monster);
    /* only safe if it was originally a struct bad_monster */
    struct bad_monster *bad_ptr = (struct bad_monster *)some_monster; 
Those are the ways I tend to break up structs when writing C code. Basically by using lots of composition.
Re:Comparing the Cost of Different Multiple-return Technique... by acqq on Tuesday December 24, 2013 @04:20AM (#6958826)
And the good aspect of C is the "flatness" of the structures: they are not "objects" with the hidden content and associated functions managing it. It's a way for the programmer to organize the data as efficiently as possible.
Re:Comparing the Cost of Different Multiple-return Technique... by acqq on Monday December 23, 2013 @06:36PM (#6957324)
Like always "divide and conquer." In a big program, I identify "subprograms" that can have only the "interface" (the very limited set of structures and functions) exposed to the rest. The subprograms aren't "libraries" in a sense that I do much faster changes to the "interface" but just having them makes everything much more maintainable. So some headers are visible only inside of the "subprogram." Second: not everything is worth to appear in headers at all: I use the functions and declarations local to the compilation unit as much as I can.

Back to the main topic, using structures properly will result in the best code you can produce for anything not trivially small. Practically every CPU I know of is specifically optimized to make addressing elements in the C structure as efficient as possible.

In your case, if there are a lot of functions to which you pass the pointer to the structure, then if you take care of the organization it means that they really do have to operate on the structure. But if you have a lot of arguments to any function, you probably need some even bigger structure and pass that around.

Re:Comparing the Cost of Different Multiple-return Technique... by klipt on Monday December 23, 2013 @03:27PM (#6956343)
> Once you recognize that, you'd probably discover that you'll be able to use the same struct in more other functions

And now you've reinvented (the basic premise of) OOP!

Re:Comparing the Cost of Different Multiple-return Technique... by acqq on Monday December 23, 2013 @04:03PM (#6956498)
I don't see that in "Fundamental features and concepts" of OOP.

http://en.wikipedia.org/wiki/Object-oriented_programming#Fun...

Let's stay on topic, talking about C. We'll avoid philosophy and hype and will keep talking about the work being done in C.

Re:Comparing the Cost of Different Multiple-return Technique... by tokenrove on Monday December 23, 2013 @08:35PM (#6957750)
It's the basis of encapsulation, which is on that list.
Re:Comparing the Cost of Different Multiple-return Technique... by acqq on Tuesday December 24, 2013 @03:41AM (#6958747)
This direction of discussion is exactly what I wanted to avoid.