Pointer to function in K&R C

Discussion in 'C Programming' started by nathan, Sep 7, 2011.

  1. nathan

    nathan Guest

    Hey there!

    I write C based software that I try to keep as portable as possible.
    Therefore I support both K&R and ANSI headers. In one of these
    headers, there is a pointer to a function with arguments. In ANSI
    that's easy, but how about K&R C? Is it:

    int foo (int (*bar) ()) {}

    or

    int foo (int (*bar) (x, y)) {}

    or:

    int foo (int (*bar) (int, int)) {}

    or (unlikely):

    int foo (int (*bar) (int x, int y)) {}

    Tnx!!
    nathan, Sep 7, 2011
    #1
    1. Advertising

  2. On Sep 7, 10:54 pm, nathan <> wrote:
    > I write C based software that I try to keep as portable as possible.
    > Therefore I support both K&R and ANSI headers.


    Are there actually any compilers that are of interest to you, that do
    not support function prototypes? Prototypes have been standard C for
    more than 20 years.

    > In one of these
    > headers, there is a pointer to a function with arguments. In ANSI
    > that's easy, but how about K&R C? Is it:


    K&R C does not have "function with argument" types. It has function
    types.

    In your header:

    int foo ();

    In your source file:

    int foo (bar, x, y)
    int (*bar) ();
    int x;
    int y;
    {
    return (*bar) (x, y);
    }

    Keep in mind that K&R C is not a actual standard, and pre-ANSI
    compilers vary in behaviour in different aspects.
    Harald van Dijk, Sep 7, 2011
    #2
    1. Advertising

  3. nathan

    Jorgen Grahn Guest

    On Wed, 2011-09-07, christian.bau wrote:
    ....
    > Of course any undefined behaviour in your program could lead to your
    > code being transported 30 years back in time, where K&R compatibility
    > could then come useful.


    That's why I include this in every program I write:

    if(time(0)<1e9) {
    FILE* f = popen("/bin/mail ", "w");
    fputs(stock_market_of_1992, f);
    fclose(f);
    }

    I'm not rich yet. I guess that means all my programs work.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Sep 7, 2011
    #3
  4. Jorgen Grahn <> writes:
    > On Wed, 2011-09-07, christian.bau wrote:
    > ...
    >> Of course any undefined behaviour in your program could lead to your
    >> code being transported 30 years back in time, where K&R compatibility
    >> could then come useful.

    >
    > That's why I include this in every program I write:
    >
    > if(time(0)<1e9) {
    > FILE* f = popen("/bin/mail ", "w");
    > fputs(stock_market_of_1992, f);
    > fclose(f);
    > }
    >
    > I'm not rich yet. I guess that means all my programs work.


    You're not rich because you're sending 1992 stock market information
    back to 2001. ((time_t)1e9 is Sun 2001-09-09 01:46:40 UTC, assuming
    Unix-style time_t).

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

    nathan Guest

    On Wed, 07 Sep 2011 14:04:20 -0700, Harald van Dijk wrote:
    > On Sep 7, 10:54 pm, nathan <> wrote:
    >> I write C based software that I try to keep as portable as possible.
    >> Therefore I support both K&R and ANSI headers.

    >
    > Are there actually any compilers that are of interest to you, that do
    > not support function prototypes? Prototypes have been standard C for
    > more than 20 years.
    >
    >> In one of these
    >> headers, there is a pointer to a function with arguments. In ANSI
    >> that's easy, but how about K&R C? Is it:

    >
    > K&R C does not have "function with argument" types. It has function
    > types.
    >
    > In your header:
    >
    > int foo ();
    >
    > In your source file:
    >
    > int foo (bar, x, y)
    > int (*bar) ();
    > int x;
    > int y;
    > {
    > return (*bar) (x, y);
    > }
    >
    > Keep in mind that K&R C is not a actual standard, and pre-ANSI compilers
    > vary in behaviour in different aspects.


    Hi Harry,
    I did some Googling last night and just didn't get the answer so I
    mixed thing up:

    The question is:

    int foo (x, y)
    int x;
    int y;
    {}

    int bar (z)
    int (*z) ();
    {}

    is this correct or do we need:

    int (*z) (int, int);
    int (*z) (x, y);

    I hope you catch my drift now. Yes, it's to maintain compatibility
    with an old system (Coherent).

    Best
    Nath
    nathan, Sep 8, 2011
    #5
  6. nathan

    Chad Guest

    On Sep 7, 2:04 pm, Harald van Dijk <> wrote:
    > On Sep 7, 10:54 pm, nathan <> wrote:
    >
    > > I write C based software that I try to keep as portable as possible.
    > > Therefore I support both K&R and ANSI headers.

    >
    > Are there actually any compilers that are of interest to you, that do
    > not support function prototypes? Prototypes have been standard C for
    > more than 20 years.
    >
    > > In one of these
    > > headers, there is a pointer to a function with arguments. In ANSI
    > > that's easy, but how about K&R C? Is it:

    >
    > K&R C does not have "function with argument" types. It has function
    > types.
    >


    I don't see why the distinction is important.

    Chad
    Chad, Sep 8, 2011
    #6
  7. On Sep 8, 8:23 pm, Chad <> wrote:
    > On Sep 7, 2:04 pm, Harald van Dijk <> wrote:
    > > On Sep 7, 10:54 pm, nathan <> wrote:
    > > > In one of these
    > > > headers, there is a pointer to a function with arguments. In ANSI
    > > > that's easy, but how about K&R C? Is it:

    >
    > > K&R C does not have "function with argument" types. It has function
    > > types.

    >
    > I don't see why the distinction is important.


    If K&R C does not have "function with argument" types, then the answer
    is "the same way as a pointer to a function without arguments".
    Harald van Dijk, Sep 8, 2011
    #7
  8. Chad <> writes:
    > On Sep 7, 2:04 pm, Harald van Dijk <> wrote:
    >> On Sep 7, 10:54 pm, nathan <> wrote:
    >>
    >> > I write C based software that I try to keep as portable as possible.
    >> > Therefore I support both K&R and ANSI headers.

    >>
    >> Are there actually any compilers that are of interest to you, that do
    >> not support function prototypes? Prototypes have been standard C for
    >> more than 20 years.
    >>
    >> > In one of these
    >> > headers, there is a pointer to a function with arguments. In ANSI
    >> > that's easy, but how about K&R C? Is it:

    >>
    >> K&R C does not have "function with argument" types. It has function
    >> types.
    >>

    >
    > I don't see why the distinction is important.


    The distinction is that a K&R C function type does not include
    information about the function's arguments.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 8, 2011
    #8
  9. nathan <> writes:
    [...]
    > I did some Googling last night and just didn't get the answer so I
    > mixed thing up:
    >
    > The question is:
    >
    > int foo (x, y)
    > int x;
    > int y;
    > {}
    >
    > int bar (z)
    > int (*z) ();
    > {}


    That's correct for K&R C.

    > is this correct or do we need:
    >
    > int (*z) (int, int);


    That's a prototype (a function declaration that includes information
    about the types of the arguments), so a pre-ANSI compiler is unlikely
    to support it. It's legal in ANSI C or later, but mixing prototypes
    and old-style function definitions like that doesn't make much sense.

    > int (*z) (x, y);


    I don't think that's not valid syntax in any version of the language
    (unless x and y are type names). (If it is valid, it only tells you how
    many parameters the function takes, not their types, and that's not
    useful.)

    > I hope you catch my drift now. Yes, it's to maintain compatibility
    > with an old system (Coherent).


    Does that system not have a C compiler that supports prototypes?
    Can you build gcc for it (probably an older version)?

    There's an old tool called "ansi2knr" (Google it) that attempts to
    convert C code with prototypes into K&R-compatible code without
    prototypes. I don't think it was ever 100% functional, but you
    might it useful.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 8, 2011
    #9
  10. nathan <> writes:

    > On Wed, 07 Sep 2011 14:04:20 -0700, Harald van Dijk wrote:
    >> On Sep 7, 10:54 pm, nathan <> wrote:
    >>> I write C based software that I try to keep as portable as possible.
    >>> Therefore I support both K&R and ANSI headers.

    <snip>
    >> Keep in mind that K&R C is not a actual standard, and pre-ANSI compilers
    >> vary in behaviour in different aspects.

    >
    > Hi Harry,


    Harry?

    > I did some Googling last night and just didn't get the answer so I
    > mixed thing up:
    >
    > The question is:
    >
    > int foo (x, y)
    > int x;
    > int y;
    > {}
    >
    > int bar (z)
    > int (*z) ();
    > {}
    >
    > is this correct


    Yes, for K&R C, that's all you need.

    > or do we need:
    >
    > int (*z) (int, int);
    > int (*z) (x, y);


    Neither is permitted by the syntax of K&R C.

    > I hope you catch my drift now. Yes, it's to maintain compatibility
    > with an old system (Coherent).


    --
    Ben.
    Ben Bacarisse, Sep 8, 2011
    #10
  11. Keith Thompson <> writes:

    > nathan <> writes:
    > [...]
    >> I did some Googling last night and just didn't get the answer so I
    >> mixed thing up:
    >>
    >> The question is:
    >>
    >> int foo (x, y)
    >> int x;
    >> int y;
    >> {}
    >>
    >> int bar (z)
    >> int (*z) ();
    >> {}

    >
    > That's correct for K&R C.
    >
    >> is this correct or do we need:
    >>
    >> int (*z) (int, int);

    >
    > That's a prototype (a function declaration that includes information
    > about the types of the arguments),


    To be picky, this is not a function declaration. It declares an
    identifier that denotes an object type rather than a function.

    As to whether it is a prototype, on the one hand section 6.2.1 p2
    defines a /function prototype/ (in italics) as "a declaration of a
    function that declares the types of its parameters". Since this does
    not declare a function, it's out. On the other hand, section 6.5.2.2 p2
    talks about an expression that denotes a called function (like the 'z'
    in 'z(1,2)') as having "a type that includes a prototype". I take that
    to mean that the above is not a function prototype but that it declares
    an object with a type that includes a prototype.

    <snip>
    >> int (*z) (x, y);

    >
    > I don't think that's not valid syntax in any version of the language
    > (unless x and y are type names).


    There's an unintended "not" I think.

    <snip>
    --
    Ben.
    Ben Bacarisse, Sep 9, 2011
    #11
  12. nathan

    James Kuyper Guest

    On 09/08/2011 02:23 PM, Chad wrote:
    > On Sep 7, 2:04 pm, Harald van Dijk <> wrote:
    >> On Sep 7, 10:54 pm, nathan <> wrote:
    >>
    >>> I write C based software that I try to keep as portable as possible.
    >>> Therefore I support both K&R and ANSI headers.

    ....
    >>> In one of these
    >>> headers, there is a pointer to a function with arguments. In ANSI
    >>> that's easy, but how about K&R C? Is it:

    >>
    >> K&R C does not have "function with argument" types. It has function
    >> types.
    >>

    >
    > I don't see why the distinction is important.


    K&R's function types were completely specified by the return type of the
    function. The "function with argument" or prototype declarations that
    were added in ANSI C also specified the number and the types of the
    arguments (I won't bother trying to describe how functions with a
    variable number of arguments complicate the description). Two prototype
    declarations are compatible only if the number of arguments match and
    the corresponding argument types are compatible.

    When you call a function that is declared with a prototype, it's a
    constraint violation to pass it the wrong number of arguments. Argument
    values are assigned to the corresponding parameters, if any such
    assignment would not be allowed, it is also a constraint violation. This
    means you generally find out at compile time if you call a function with
    the wrong number or wrong types of arguments.

    For functions declared with K&R syntax, there's nothing to be checked,
    and you won't find out that you've made such errors until run-time (and
    not necessarily then, either, depending upon precisely how the function
    call actually malfunctions).
    --
    James Kuyper
    James Kuyper, Sep 9, 2011
    #12
  13. nathan

    Jorgen Grahn Guest

    On Thu, 2011-09-08, Keith Thompson wrote:
    > Jorgen Grahn <> writes:
    >> On Wed, 2011-09-07, christian.bau wrote:
    >> ...
    >>> Of course any undefined behaviour in your program could lead to your
    >>> code being transported 30 years back in time, where K&R compatibility
    >>> could then come useful.

    >>
    >> That's why I include this in every program I write:
    >>
    >> if(time(0)<1e9) {
    >> FILE* f = popen("/bin/mail ", "w");
    >> fputs(stock_market_of_1992, f);
    >> fclose(f);
    >> }
    >>
    >> I'm not rich yet. I guess that means all my programs work.

    >
    > You're not rich because you're sending 1992 stock market information
    > back to 2001. ((time_t)1e9 is Sun 2001-09-09 01:46:40 UTC, assuming
    > Unix-style time_t).


    Ah, thanks. I actually *did* the math, but messed up on the
    requirements. (And late 2001 was probably not the best time to make
    money on stocks anyways; the IT bubble burst some months later as I
    recall it.)

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Sep 9, 2011
    #13
  14. nathan

    Jorgen Grahn Guest

    On Thu, 2011-09-08, Keith Thompson wrote:
    > nathan <> writes:

    ....

    >> I hope you catch my drift now. Yes, it's to maintain compatibility
    >> with an old system (Coherent).

    >
    > Does that system not have a C compiler that supports prototypes?
    > Can you build gcc for it (probably an older version)?


    Googling on "gcc Coherent" shows among other things
    http://www.coherentos.info/cohs-gcc-usefulness
    You can buy (?) GCC for Coherent from someone named "MWC"
    apparently.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Sep 9, 2011
    #14
  15. nathan

    James Kuyper Guest

    On 09/09/2011 05:25 AM, Jorgen Grahn wrote:
    > On Thu, 2011-09-08, Keith Thompson wrote:

    ....
    >>
    >> You're not rich because you're sending 1992 stock market information
    >> back to 2001. ((time_t)1e9 is Sun 2001-09-09 01:46:40 UTC, assuming
    >> Unix-style time_t).

    >
    > Ah, thanks. I actually *did* the math, but messed up on the
    > requirements. (And late 2001 was probably not the best time to make
    > money on stocks anyways; the IT bubble burst some months later as I
    > recall it.)


    Which would have made it an excellent time to sell short. If you know
    what the market's going to do, you can almost always make money off of
    your knowledge.
    --
    James Kuyper
    James Kuyper, Sep 9, 2011
    #15
  16. Ben Bacarisse <> writes:
    > Keith Thompson <> writes:
    >> nathan <> writes:

    [...]
    >>> int (*z) (x, y);

    >>
    >> I don't think that's not valid syntax in any version of the language
    >> (unless x and y are type names).

    >
    > There's an unintended "not" I think.
    >
    > <snip>


    Yes, thanks.

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

    Tim Rentsch Guest

    Ben Bacarisse <> writes:

    > Keith Thompson <> writes:
    >
    >> nathan <> writes:
    >> [...]
    >>> I did some Googling last night and just didn't get the answer so I
    >>> mixed thing up:
    >>>
    >>> The question is:
    >>>
    >>> int foo (x, y)
    >>> int x;
    >>> int y;
    >>> {}
    >>>
    >>> int bar (z)
    >>> int (*z) ();
    >>> {}

    >>
    >> That's correct for K&R C.
    >>
    >>> is this correct or do we need:
    >>>
    >>> int (*z) (int, int);

    >>
    >> That's a prototype (a function declaration that includes information
    >> about the types of the arguments),

    >
    > To be picky, this is not a function declaration. It declares an
    > identifier that denotes an object type rather than a function.
    >
    > As to whether it is a prototype, on the one hand section 6.2.1 p2
    > defines a /function prototype/ (in italics) as "a declaration of a
    > function that declares the types of its parameters". Since this does
    > not declare a function, it's out. On the other hand, section 6.5.2.2 p2
    > talks about an expression that denotes a called function (like the 'z'
    > in 'z(1,2)') as having "a type that includes a prototype". I take that
    > to mean that the above is not a function prototype but that it declares
    > an object with a type that includes a prototype. [snip unrelated]


    That's simply bad wording in this definition; presumably what was
    meant is 'function declarator'. Clearly the Standard intends the
    term 'function prototype' to include things like declarations of
    pointer-to-function types, otherwise other passages in the Standard
    are nonsensical -- cf. 6.2.1 p4. I agree the wording in 6.2.1p2 is
    poorly chosen, but surely the intended meaning is clear.
    Tim Rentsch, Jan 24, 2012
    #17
    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. glen stark
    Replies:
    2
    Views:
    702
    Ron Natalie
    Oct 10, 2003
  2. Fraser Ross
    Replies:
    4
    Views:
    1,042
    Fraser Ross
    Aug 14, 2004
  3. murgan
    Replies:
    6
    Views:
    4,861
    Thad Smith
    Dec 21, 2005
  4. Vijai Kalyan
    Replies:
    4
    Views:
    704
    Vijai Kalyan
    Nov 8, 2005
  5. Replies:
    3
    Views:
    306
    Philip Potter
    Apr 11, 2008
Loading...

Share This Page