Is goto Still Considered Harmful?

Discussion in 'C Programming' started by Lynn McGuire, Mar 12, 2014.

  1. Lynn McGuire

    Stefan Ram Guest

    My assertion is that in C we (the majority of educated
    programmers of today) prefer short functions. I do not wish
    to make any assertion about whether this holds or does not
    hold for any other language.
    Stefan Ram, Mar 25, 2014
    1. Advertisements

  2. I'm sure that Jim & Kiki realized a few posts ago what you meant [*], but
    it is their nature that they can't admit it now. They're committed to
    seeing this through on the assumption that their (mis-) understanding of
    what you wrote is the only possible interpretation.

    It's a lot like the Catholic church. Their doctrine of infallibility means
    that they can never, ever admit to having made a mistake [**].

    [*] I.e., that you were simply making a statement of the form: Stop signs
    are red. Note that this doesn't say anything about any other kind of signs
    (other types of signs may or may not be red, but this doesn't in any way
    impinge on the truth of the assertion that stop signs are red).

    [**] In fairness, it must be noted that Kiki (and others like him) do on
    occasion admit to being on technical matters (which in the context of this
    newsgroup means specifically: interpretation of the C standards documents),
    but I have never seen them admit to having misunderstood another posters
    post (i.e., intentions). On these matters, Kiki, James, et al, are, like
    the RCC, infallible.
    Kenny McCormack, Mar 25, 2014
    1. Advertisements

  3. Lynn McGuire

    Kaz Kylheku Guest

    I prefer functions not to be "unnecessarily long".

    Sometimes "necessarily long" can mean a thousand lines or more.

    If a large function is broken up into a small top function which calls many
    smaller ones, but those smaller ones have no caller other than the top
    function, then the change is pretty much a waste of effort.

    Not only that, but C has poor support for dividing logic into functions.
    Breaking up a large function into smaller ones can mean changing the structure
    of the code in order to simulate the environment passing that naturally occurs
    in a language with nested functions. What were originally nice, local
    variables in the original function turn into some ugly structure or structures
    that only exists in order to support the fragmentation of the logic into
    multiple functions. These can harm the performance of the function, and also
    trade back some of the maintainbility improvement arising from the breakup.

    So, it is perfectly okay for some complicated, self-contained piece of logic
    which offers no re-usable small pieces to any other part of the program to be
    be represented as a big function that works with a bunch of local variables.

    Breaking up logic into functions should only be done when:

    - some of those functions will be called from more than one place, eliminating

    - some of those functions are useful on their own and will end up being
    called by other functions or modules.

    - pieces of the original large code were being selectively dispatched by
    a large switch or if/else ladder, so that when the function is broken up,
    a dispatch based on function pointer indirection can streamline the flow
    and possibly even be faster.

    Experienced, mature programmers can handle large functions, and large functions
    occur in all advanced, real-world projects.

    For instance, the function _dl_map_object_from_fd in the glibc dynamic linker:;a=blob;f=elf/dl-load.c

    goes from line 919 to 1623. (Commit 9455df...bef85a).

    People always wish that the world conform to their own physical and
    intellectual limitations. Grapes that are out of reach must be sour,
    thought the Fox.

    Maybe the real principle here is "small functions for small minds".
    Kaz Kylheku, Mar 25, 2014
  4. Lynn McGuire

    Ken Brody Guest

    And this qualifies as "without going through hoops", how?

    I can't begin to picture the complexity of f1(), etc., especially with
    regards to local variables within some_function().
    Ken Brody, Mar 25, 2014
  5. Lynn McGuire

    Ian Collins Guest

    Not if you are unit testing the functions, which I guess counts as them
    having more than one caller... I have never seen or written long
    functions in code developed using TDD.
    Ian Collins, Mar 25, 2014
  6. (snip, someone wrote)
    Maybe not. An APL program could be way too long at one page.
    Some say unreadable no matter how short.

    For assembler, programs naturally tend to be longer.

    But yes, for a wide variety of languages the optimal length is
    probably not too different from C.

    -- glen
    glen herrmannsfeldt, Mar 25, 2014
  7. C does require functions to be recursive, but most aren't.
    The mathematical meaning of the word FUNCTION doesn't require
    it to be recursive.

    But Fortran did in 1990 add recursion, though it must be declared
    as an attribute to such functions.

    There is an additional complication in Fortran, in that inside a
    function the name of the function is normally a variable name, not
    a function name. This can be changed in Fortran 90 and later to
    allow for direct recursion.

    -- glen
    glen herrmannsfeldt, Mar 25, 2014
  8. Procedural decomposition is largely for the benefit of the programmer, not the
    I'll happily write trivial little functions. They often make code clearer.
    red = clamp(red, 0, 255)

    is obvious, writing it out as two ternary expressions obscures what you are

    If you've got difficulty breaking up large functions, the secret is often
    to declare structures to hold related units of data. Functions then naturally
    operate on those structures. They're not reusable, of course, but they do
    make logical sense. For example if you're doing a flood fill, you can have
    the border pixel queue as a struct QUEUE. All the memory management and
    circular buffer code is abstracted, and you can see the basic logic.
    Since structs can be declared in file scope, you're not polluting namespace.
    Malcolm McLean, Mar 25, 2014
  9. I don't really follow what Stefan is trying to do, although I suspect
    that it's more of a way to handle a decision tree than Ken's example of
    cleaning up state. And Ken's code sample is missing the most compelling
    argument for the "cleanup goto": often the clean_up() functionality
    *can't* be moved into its own function, because it needs access to local
    Lowell Gilbert, Mar 26, 2014
  10. Lynn McGuire

    Stefan Ram Guest

    I you would provide a specific example (without »...«), I
    might then show how to refactor it to the style I prefer.
    Stefan Ram, Mar 26, 2014
  11. Lynn McGuire

    Stefan Ram Guest

    Supersedes: <>

    If you or someone else would provide a specific example
    (without »...«), I might then show how to refactor it to
    the style I prefer.
    Stefan Ram, Mar 27, 2014
  12. Lynn McGuire

    Ken Brody Guest

    Any APL program longer than 1 line is too long. :)

    Ken Brody, Mar 27, 2014
  13. Lynn McGuire

    John Bode Guest

    Large functions are not necessarily *hard* to debug, if you can be certain
    of the control flow. I'm arguing that adding gotos to the mix makes a bad
    situation worse.

    The gotos were what made that particular code unfixable, not the size of
    it; the logic was impenetrable because the code branched all
    over the goddamned place with no apparent rhyme or reason. Even when
    we did eventually figure it out, we could not fix anything without breaking
    something elsewhere in the code; it was so tightly coupled with itself
    that any change only degraded it.
    Who's "we"?

    I've written very large functions in the past, usually because I was
    dealing with a brain-dead, simple-but-tedious-to-use interface where
    the code was on the order of

    huge_struct.a_member = a_value;
    huge_struct.another_member = another_value;
    huge_struct.yet_another_member = yet_another_value;
    huge_struct.omg_how_many_of_these_things_are_there = gaaaaahhhhh;
    do_something_with( huge_struct );

    repeated multiple times with multiple huge_struct types; individual
    functions could top out at 500-800 SLOC, 80% of those being simple
    assignment statements because the API was *stupid*.
    For that particular program, we told the customer we could either rewrite
    it from scratch or they could buy faster hardware to meet their performance

    They bought the faster hardware.
    John Bode, Mar 27, 2014
  14. Lynn McGuire

    Stefan Ram Guest

    The collective of C programmers who write short functions in C.
    Stefan Ram, Mar 27, 2014
  15. Lynn McGuire

    James Kuyper Guest

    That's close to being a tautology: of course people who write short
    functions tend to believe that functions should be short. Your comment
    would have been more meaningful if you could have, correctly, used "we"
    to refer to a larger, or at least more authoritative, group of people.
    James Kuyper, Mar 28, 2014
  16. Just can't admit that you f*cked up, can you?

    (As I described in my earlier post...)
    Kenny McCormack, Mar 28, 2014
  17. Outlawing anything more than 16 lines or banning more than one return
    statement are the action of small minded types with no bigger picture.[/QUOTE]

    Otherwise known as "CLC regs".

    Hence, this sub-thread topic is right up their alley.

    But the Bush apologists hope that you won't remember all that. And they
    also have a theory, which I've been hearing more and more - namely,
    that President Obama, though not yet in office or even elected, caused the
    2008 slump. You see, people were worried in advance about his future
    policies, and that's what caused the economy to tank. Seriously.

    (Paul Krugman - Addicted to Bush)
    Kenny McCormack, Mar 28, 2014
  18. If a paragraph goes over half a page I'd break it up. It does depend what
    you're writing - fiction needs continuous flow, so the chapters are about
    2,000 words, with these days maybe the odd blank line to break up sections.
    Technical writing has far more short sections with headings.
    Early C reserved a keyword, I think it was called "entry" to indicate that
    a function could be called from more than one point. It was never implemented,
    and the consensus is that it was a bad idea.
    Personally I use a variable called "answer" as the return for most functions,
    and the function end "return answer". I try to have only one return, but
    I'll occasionally return early on aborts (e.g. a statistical function called
    with N = 0), and I won't fuss about a terminal if(conditon) return true else
    return false. I won't write it as return (condition), which is harder to
    Malcolm McLean, Mar 28, 2014
  19. Lynn McGuire

    Stefan Ram Guest

    When you write a function »double average( int const N ...«,
    what value do you return on an abort?
    Stefan Ram, Mar 28, 2014
  20. (snip)
    Fortran and PL/I have ENTRY, and sometimes it is convenient and
    useful. For example, SIN and COS, written in assembly, are commonly
    one routine that does argment reduction differently, but then goes
    into the rest of the computation in common.

    I was once debugging with gdb a gfortran program with ENTRY, and
    was surprised at what it did. gfortran uses the same back end as
    gcc, which it seems can't generate ENTRY. The result is one function
    for each entry point, which then calls another with the appropriate
    combination of arguments.

    I believe it is depricated in Fortran, probably not in PL/I.

    -- glen
    glen herrmannsfeldt, Mar 28, 2014
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.