Good practice of using void function return type?

Discussion in 'C Programming' started by dspfun, May 15, 2014.

  1. What's wrong with it is that the word "function" already has a well
    defined meaning in C, and "procedure" has a well defined meaning
    in a number of other programming languages.

    The vast majority of programmers, if asked about the difference
    between a function and a procedure, will say that a function
    returns a value and a procedure doesn't, and will likely add that
    C's version of a procedure is a void function.

    You are, once again, insisting on using established words with
    meanings that differ greatly from the way they're used *in the
    context of programming*.

    And how does your quoted definition of "procedure":

    procedure
    A process is a set or series of actions directed to some end or a
    natural series of changes; a procedure is a series of actions
    conducted in a certain manner, an established way of doing
    something.

    imply that it performs I/O? Surely a subroutine that does nothing
    but bit twiddeling would qualify as a "procedure" under that
    definition.

    Do you also use the English language dictionary definitions of
    "pointer", "variable", and "object" when discussing C programming?
    (The use of "variable" in your quoted definition of "function"
    is entirely inconsistent with the way it's commonly used in
    programming.)

    Let me rephrase the question I asked earlier: Can you cite an
    independent source that uses the words "procedure" and "function"
    in the way you do *in the context of computer programming*?
    (An English dictionary definition does not qualify.)

    If you don't wish to communicate, there are easier ways.
     
    Keith Thompson, May 15, 2014
    #21
    1. Advertisements

  2. I don't recall anyone stating an assumption that the program's internal
    state is corrupted. I though we were talking about error conditions in
    general. (For example, if a program's only job is to write information
    to stdout, aborting could be a reasonable reponse to a failure in
    printf().)
     
    Keith Thompson, May 15, 2014
    #22
    1. Advertisements

  3. dspfun

    Joe Pfeiffer Guest

    First, it isn't the definition you gave before, and it isn't citing a
    dictionary. Second, it isn't the definition used in C, which is what's
    relevant here.
    Well, yes, when discussing programming languages that's a very good
    reason to use it in the same special sense they do. I'm still trying to
    figure out what that has to do with performing I/O, though.
     
    Joe Pfeiffer, May 15, 2014
    #23
  4. dspfun

    Joe Pfeiffer Guest

    It isn't true of procedures in general strikes me as a perfectly good
    reason to call it "wrong".
     
    Joe Pfeiffer, May 15, 2014
    #24
  5. Another approach might be to give it a return value that indicates
    whether it succeeded, but have it always return 0 to indicate
    success. An advantage is that the interface doesn't have to
    be changed if it's later modified so it can detect errors; also,
    perhaps client code shouldn't have to care which functions can fail
    and which can't. A disadvantage is that any error handling code
    will never be executed, and so can't be tested.
    When would ferror(stdout) be true?
    Another interesting case is the standard free() function, which can fail
    catastrophically if the system's internal data structures have been
    corrupted, but it has no way to report an error. Any such failure is a
    consequence of undefined behavior, so there's no good way to handle it
    anyway.
     
    Keith Thompson, May 15, 2014
    #25
  6. dspfun

    BartC Guest

    What's wrong about it is that a function can also activate an external
    device, while a procedure can also shuffle bits in memory. They can both do
    exactly the same things.

    It's just that one directly returns a value (allowing it to be used in an
    expression) and the other doesn't.
     
    BartC, May 15, 2014
    #26
  7. dspfun

    Ian Collins Guest

    So if I go in to hospital for a minor repair, is the surgeon performing I/O?
     
    Ian Collins, May 15, 2014
    #27
  8. dspfun

    Ian Collins Guest

    It also performs I?O, so in Malcolm's vocabulary, it's a procedure. Oh
    wait, it returns a value so it must be a function. Oh wait, it does I/O
    so it must be a procedure... Repeat until done.
     
    Ian Collins, May 15, 2014
    #28
  9. (snip)
    As far as I know, in many cases PROCEDURE is uses as the generic
    form, for either subroutine (void function) or function (returning
    a value). I believe it is used that way now in the Fortran standard,
    for example in the case of procedure pointers.
    It gets a little complicated, as words sometimes have a generic
    computer science meaning that is different from the meaning in
    some languages. If the language doesn't define the meaning, then
    the generic CS meaning should be considered.

    -- glen
     
    glen herrmannsfeldt, May 15, 2014
    #29
  10. dspfun

    James Kuyper Guest

    A status check is necessary whenever something can go wrong. Lots of
    statements have no possible failure mode, so there's no need to check
    anything. The only significance of the function body is that a single
    logical line of code in the caller results in the execution of many
    lines in the called routine, increasing the likelihood that there's at
    least one thing that could go wrong, and must therefore be reported. The
    actual behavior should be the same, whether or not the code is wrapped
    in a separate function body.

    That's not quite true: I trust data values passed between different
    parts of the same translation unit (TU), because it's generally easy to
    confirm that they have been validated at least once before use. However,
    whenever data is passed into one TU from some other part of the program,
    I don't trust it, and insist on validating it. For instance, I check
    pointers to make sure they're not null, and I take numbers that
    determine what parts of an array will be used, and make sure they don't
    have values that would result in out-of-range array accesses.

    Therefore, if a bunch of lines in one function is pulled out, and put
    into a separate function, *and the separate function is put in a
    different TU*, then that separate function needs to validate all of the
    values passed to it, and the calling function needs to validate any
    information returned to it by that function. But this isn't because it's
    a function, it's because it's in a separate TU.

    If you are willing to trust across TU boundaries, then you would have a
    correspondingly smaller need to validate data values.
    Why are you talking about assignment statements? I'm talking about
    checking function calls; in particular, function calls that can fail,
    for whatever reason - the reason depends upon the function. What I'm
    checking for is, as indicated above, is whether or not the function
    actually did fail. If the function can't fail, there's no need to check.
    If it can fail, what seems odd to you about the fact that I want to
    check whether it did?

    ....
    Yes, exactly.
     
    James Kuyper, May 15, 2014
    #30
  11. dspfun

    James Kuyper Guest

    Yes, that's how it was originally written. It was actually a macro named
    PGS_S_SUCCESS, but that macro happens to be #defined to 0.
    In principle, that's always a possibility, but it seemed exceedingly
    unlikely in this case. Unfortunately, I don't remember the details - but
    the function body was no more than about three lines long; there just
    wasn't much room for any detectable problem to occur, nor any plausible
    reason why the function might someday be given larger responsibilities.
    It's because of that disadvantage that I choose to modify the routine.

    ....
    When there's an I/O error while writing to stdout. That seems obvious,
    so I suspect I've missed some aspect of your question.
     
    James Kuyper, May 15, 2014
    #31
  12. Oops! What I meant to write was:

    When would feof(stdout) be true?

    [...]
     
    Keith Thompson, May 15, 2014
    #32
  13. dspfun

    James Kuyper Guest

    That makes more sense!

    I had a vague idea that feof(stdout) should be true if stdout is
    redirected to a file, and the file system that it's writing to runs out
    of space, but a quick review of what the standard says about
    "end-of-file" provides no support for that idea. I guess that should be
    counted as an I/O error?

    For 18 years now, most of the programs I've written do I/O mainly
    through third-party libraries (HDF, HDF-EOS, and the SDP Toolkit),
    rather than <stdio.h>. I don't use feof() or ferror() anywhere near as
    often as I used to before I started work on this project. I don't think
    I've got any code that passes an input file to feof(), but I suppose I
    should check to make sure.
     
    James Kuyper, May 15, 2014
    #33
  14. He's performing what's normally called an "operation", from the Latin word
    for "work", or a manipulation of the external environment.

    A procedure is a sort of format or instruction set for an "operation",
    or a "work". Now is an internal action an action? It's another case of
    marginal set membership. Sometime we say that if a device is performing
    internal actions but nothing externally, then it's "idling" or "doing
    nothing". Other times we say "it's doing something to itself". It depends
    on context. Sometimes an "action" must be external. If we say to the
    putative surgeon, "how many people did you repair today?", and he had
    three patients in theatre, but he also has a scratch on his leg which
    slowly healing, normally you'd expect him to say "three", the marginal
    case is excluded. But if you then point to the scratch on his leg
    and say "why is that scabbing over?", he might say "it's repairing
    itself". If you say "so actually you repaired four people today",
    he might admit that you are in a sense correct.

    Now if a computing device performs IO, that's another way of saying
    that it manipulates something in the external environment. So
    that's a core member of the set of "actions". If the computer
    is moving space invaders about the screen in response to player
    input, no one would say it's "idling". What if it's turned on
    and in fact running the processor? It's a marginal case. Often
    we'd say "it's not doing anything".

    Now my use f the term "procedure" excludes the marginal case of
    internal actions. That's normal and natural. You can sometimes
    use the word in another context, e.g. "this procedure will remove
    all the invalid pointers from the list". Now we're treating an
    internal action as qualifying. Again, that's perfectly normal,
    natural and unproblematic. By definition, marginal members of
    a set are sometime included, sometimes included.

    It's all perfectly simple, intuitive, and obvious, unless you
    try to apply a mathematical mindset to English speech.
     
    Malcolm McLean, May 15, 2014
    #34
  15. dspfun

    Ike Naar Guest

    That distinction seems a bit artificial.

    There are functions that do both: many functions that do I/O also
    shuffle bits about in the computer memory. If the I/O device is
    mapped in memory (like, say, a file in a tmpfs filesystem under
    linux, or an unnamed pipe) then a function that "does I/O" does in
    fact nothing more than shuffle bits about in memory.

    And then there are functions that do neither, e.g. sleep().
     
    Ike Naar, May 15, 2014
    #35
  16. dspfun

    Joe Pfeiffer Guest

    In this case, of course, everyone else in the discussion is applying a
    mathematical mindset to a mathematical object (a program).
     
    Joe Pfeiffer, May 15, 2014
    #36
  17. A compiler can't use natural language. So I've given a crisp,
    unambiguous definition of "function" and "procedure" which can
    coded and enforced automatically. A function can only shuffle bits
    about in the computer's memory, it can't do IO. (So it can't read
    any bits, for example, which might be affected by an external
    device in the course of execution, the state of the program on
    function exit is always completely defined by the state on function
    entry). A procedure can do IO. So a procedure may call a function
    or another procedure, but a function may not call a procedure.

    But you can't apply the crisp, programming definition to the English
    word "procedure" itself and say "That's what it means. It means what
    Malcolm has said and may never be used in any other context." Or
    alternatively, "Malcolm has no right to use that word. He must invent
    a special one". That's the inappropriate mathematical thinking.
     
    Malcolm McLean, May 15, 2014
    #37
  18. dspfun

    luser droog Guest

    Hmmmm. What if Kenny and Keith are the same person,
    playing a long-con smeagol/Gollum soliloquy for us.
     
    luser droog, May 16, 2014
    #38
  19. And these "crisp, unambiguous" definitions of yours blatantly
    conflict with the way those words are routinely used *in the context
    in which you're using them*.

    [...]
    The relevant context is programming, not mathematics. Mathematical
    functions and software functions are, or at least can be, quite
    different.

    If this many people were unanimously telling me that I was using words
    in a confusing manner, I'd seriously consider the possibility that they
    were right and I was wrong.
     
    Keith Thompson, May 16, 2014
    #39
  20. dspfun

    David Brown Guest

    You really like these personal Malcolm McLean specific definitions that
    are "obvious" to "normal" English speakers, don't you?

    In normal English, the word "function" has multiple meanings. It also
    has a particular meaning in mathematics, multiple meanings in computer
    science, and a specific definition in C. You don't get to pick one of
    these and call it /the/ definition, and then blame C for disagreeing
    with you.

    This is a C newsgroup - we talk mostly about C, or related topics. So
    when you use the word "function", everyone here understands it to mean
    "C function", unless the context makes it clear (such as "the function
    of this software is to annoy the user as efficiently as possible"). If
    you want to talk specifically about functions that produce results
    dependent solely on their inputs, and have no side-effects, then these
    are commonly referred to as "pure functions".

    There are no commonly used terms to make the distinctions you describe
    between "functions that shuffle bits around" and "procedures that do
    IO". So if you want to talk about these, you have to say what you mean,
    such as "functions with externally visible effects".
     
    David Brown, May 16, 2014
    #40
    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.