Re: void arguments

Discussion in 'C Programming' started by Malcolm McLean, Jan 17, 2011.

  1. On Jan 17, 10:20 am, Cross <> wrote:
    > Hello
    >
    > I would like to know the difference between the following:
    >
    > void func();
    > void func(void);
    >

    When C was being developed there was a certain looseness with
    arguments. You could call the same function with one argument or two
    arguments, as long as it didn't actually use unpassed arguments.

    It was later decided that this was a bad idea. However the old way had
    to be kept for backwards compatibility.

    so void func() means func takes zero or more arguments, and returns
    nothing
    void func(void) means func takes zero arguments.
     
    Malcolm McLean, Jan 17, 2011
    #1
    1. Advertising

  2. Malcolm McLean

    Seebs Guest

    On 2011-01-17, Malcolm McLean <> wrote:
    > When C was being developed there was a certain looseness with
    > arguments. You could call the same function with one argument or two
    > arguments, as long as it didn't actually use unpassed arguments.


    So far as I know, it has always been an error, in general, to do this
    (the weird exception being open()...).

    > It was later decided that this was a bad idea. However the old way had
    > to be kept for backwards compatibility.


    No, it didn't.

    You're conflating two separate things, one is the old-style function call
    semantics (from back when you couldn't declare argument lists), the other
    is an entirely different question of call sequences. Even back before
    prototypes, it was possible for code to fail interestingly if you passed
    the wrong number of arguments, whether or not they were "used".

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
     
    Seebs, Jan 17, 2011
    #2
    1. Advertising

  3. Malcolm McLean <> writes:
    > On Jan 17, 10:20 am, Cross <> wrote:
    >> I would like to know the difference between the following:
    >>
    >> void func();
    >> void func(void);
    >>

    > When C was being developed there was a certain looseness with
    > arguments. You could call the same function with one argument or two
    > arguments, as long as it didn't actually use unpassed arguments.


    I'm not sure that all implementations behaved this way, but it's
    quite possible that they did. Since there was no special syntax
    (before the 1989 C standard) for variadic functions, this kind of
    looseness was necessary to implement printf() and friends.

    > It was later decided that this was a bad idea. However the old way had
    > to be kept for backwards compatibility.


    Not entirely.

    > so void func() means func takes zero or more arguments, and returns
    > nothing
    > void func(void) means func takes zero arguments.


    The *definition* of func() specifies the exact number and type(s) of any
    arguments it expects. The only remaining looseness is that, if it's
    *declared* as "void func()", the compiler isn't required to diagnose
    calls that pass the wrong number and/or type(s) of arguments. Any call
    that's inconsistent with the definition has undefined behavior.

    For example:

    void func(void) { ... }
    /* definition, func has no parameters */

    /* in another source file: */
    void func();
    ...
    func(42); /* undefined behavior, compiler is unlikely to complain */

    /* in yet another source file: */
    void func(void);
    ...
    func(42); /* constraint violation, the compiler must diagnose */

    "void func()" is an old-style non-prototype function declaration.
    Such declarations have been officially obsolescent since the
    1989 ANSI C standard, and may be removed altogether in some future
    standard. There are a few obscure cases where they might be useful,
    but not IMHO enough to justify either using them or leaving them
    in the language.

    If you want to discuss whether they should be removed from the
    standard, see the thread "Time to remove old-style function
    declarations?" in comp.std.c.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 17, 2011
    #3
  4. Seebs <> writes:
    > On 2011-01-17, Malcolm McLean <> wrote:
    >> When C was being developed there was a certain looseness with
    >> arguments. You could call the same function with one argument or two
    >> arguments, as long as it didn't actually use unpassed arguments.

    >
    > So far as I know, it has always been an error, in general, to do this
    > (the weird exception being open()...).


    I mentioned elsethread that printf() and friends might be another
    example, depending on the implementation.

    Looking into it a bit further, printf() would have been defined as
    something like:

    #include <varargs.h>
    printf(char *format, va_list)
    va_dcl
    {
    va_list ap;
    ...
    }

    The expansion of va_list and va_dcl could do whatever compiler-specific
    magic is needed to handle a variable number and type of arguments, so
    even in pre-ANSI C, there was no requirement for an ordinarily defined
    function to be able to handle anything other than a fixed number and
    type of arguments.

    Of course <varargs.h> has been superseded by <stdarg.h> and the ", ..."
    syntax.

    [...]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 17, 2011
    #4
  5. Keith Thompson <> writes:

    > Seebs <> writes:
    >> On 2011-01-17, Malcolm McLean <> wrote:
    >>> When C was being developed there was a certain looseness with
    >>> arguments. You could call the same function with one argument or two
    >>> arguments, as long as it didn't actually use unpassed arguments.

    >>
    >> So far as I know, it has always been an error, in general, to do this
    >> (the weird exception being open()...).

    >
    > I mentioned elsethread that printf() and friends might be another
    > example, depending on the implementation.


    It certainly was in K&R (first edition) C. There is statement to the
    effect that it is "generally safe" to handle a variable number of
    arguments provided that the program does not use the value of an
    argument that was not supplied.

    In this regard, modern C does not support non-prototype (K&R) functions
    as they were originally envisaged because it is not "generally safe" to
    do this anymore, though one could make the point that "generally safe"
    and "undefined behaviour" are, formally, the same thing!

    K&R also says that printf (and functions like it) can't be written
    portably, but it does not go so far as to say how they may be
    implemented at all. The usual technique was to take the address of the
    first argument and adjust it to find the others. You'd need to know the
    sizes of the promoted types and the direction to adjust it. Of course,
    this was not guaranteed to work, but it often did work and was sometimes
    done.

    This was no help when the code has to pass the arguments on. With no
    equivalent of the vfprintf family of functions, one sometimes saw code
    like this:

    int debug_print(fmt, a, b, c, d, e, f, g, h)
    char *fmt;
    int a, b, c, d, e, f, g, h;
    {
    /* ... */
    fprintf(stderr, fmt, a, b, c, d, e, f, g, h);
    /* ... */
    }

    that imposes an upper limit on the length of the argument list.

    > Looking into it a bit further, printf() would have been defined as
    > something like:
    >
    > #include <varargs.h>
    > printf(char *format, va_list)
    > va_dcl
    > {
    > va_list ap;
    > ...
    > }
    >
    > The expansion of va_list and va_dcl could do whatever compiler-specific
    > magic is needed to handle a variable number and type of arguments, so
    > even in pre-ANSI C, there was no requirement for an ordinarily defined
    > function to be able to handle anything other than a fixed number and
    > type of arguments.


    K&R C had no varargs.h so you were on your own. I can't remember when
    varags.h first came alone, but it was quite early on.

    > Of course <varargs.h> has been superseded by <stdarg.h> and the ", ..."
    > syntax.


    --
    Ben.
     
    Ben Bacarisse, Jan 17, 2011
    #5
  6. Malcolm McLean

    ec429 Guest

    On 17/01/11 20:42, Ben Bacarisse wrote:
    > Keith Thompson<> writes:
    >
    >> Seebs<> writes:
    >>> On 2011-01-17, Malcolm McLean<> wrote:
    >>>> When C was being developed there was a certain looseness with
    >>>> arguments. You could call the same function with one argument or two
    >>>> arguments, as long as it didn't actually use unpassed arguments.
    >>>
    >>> So far as I know, it has always been an error, in general, to do this
    >>> (the weird exception being open()...).

    >>
    >> I mentioned elsethread that printf() and friends might be another
    >> example, depending on the implementation.

    >
    > It certainly was in K&R (first edition) C. There is statement to the
    > effect that it is "generally safe" to handle a variable number of
    > arguments provided that the program does not use the value of an
    > argument that was not supplied.
    >
    > In this regard, modern C does not support non-prototype (K&R) functions
    > as they were originally envisaged because it is not "generally safe" to
    > do this anymore, though one could make the point that "generally safe"
    > and "undefined behaviour" are, formally, the same thing!

    Well I guess definitions of "generally" vary, but to a mathematician, to
    state that something is "generally true" is to state that it is true "in
    full generality", ie. for all cases. In that sense, undefined behaviour
    is canonically _not_ "generally safe", indeed it is not "generally"
    anything as it is undefined; any statement you make about the
    manifestation of a given UB fails to be generally true as a conforming
    compiler could be created specifically to disagree with your statement.
    Just a pointless quibble, like much in this group ;)
    -Edward
    --
    'sane', adj.: see 'unimaginative'
    on the web - http://jttlov.no-ip.org
     
    ec429, Jan 17, 2011
    #6
  7. In article <ih2j2c$9if$-september.org>,
    ec429 <> wrote:
    ....
    >Well I guess definitions of "generally" vary, but to a mathematician, to
    >state that something is "generally true" is to state that it is true "in
    >full generality", ie. for all cases. In that sense, undefined behaviour
    >is canonically _not_ "generally safe", indeed it is not "generally"
    >anything as it is undefined; any statement you make about the
    >manifestation of a given UB fails to be generally true as a conforming
    >compiler could be created specifically to disagree with your statement.


    I think it is pretty clear that when we say something like "generally
    safe", we are using the vernacular meaning, which is, as you note,
    pretty much the opposite of the mathematician's meaning.

    >Just a pointless quibble, like much in this group ;)


    You got that right, buddy!

    --
    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, Jan 18, 2011
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sergio

    returning a void (*)(void)

    Sergio, Jan 5, 2005, in forum: C++
    Replies:
    6
    Views:
    454
    Jonathan Turkanis
    Jan 5, 2005
  2. Ollej Reemt
    Replies:
    7
    Views:
    605
    Jack Klein
    Apr 22, 2005
  3. Stig Brautaset

    `void **' revisited: void *pop(void **root)

    Stig Brautaset, Oct 25, 2003, in forum: C Programming
    Replies:
    15
    Views:
    841
    The Real OS/2 Guy
    Oct 28, 2003
  4. Replies:
    5
    Views:
    886
    S.Tobias
    Jul 22, 2005
  5. Replies:
    1
    Views:
    439
    Victor Bazarov
    May 23, 2007
Loading...

Share This Page