Pointer to function in K&R C

  • Follow


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!!
0
Reply spamtrap6468 (12) 9/7/2011 8:54:33 PM

On Sep 7, 10:54=A0pm, nathan <spamt...@trashcan.invalid> 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.
0
Reply truedfx (1926) 9/7/2011 9:04:20 PM


On Sep 7, 9:54=A0pm, nathan <spamt...@trashcan.invalid> wrote:
> 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:

I think the last time I heard of anyone giving up on pre-ANSI C
compatibility was about sixteen years ago.
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.
0
Reply christian.bau1 (402) 9/7/2011 9:08:48 PM

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 me@student.foo.edu", "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   .
0
Reply nntp24 (1559) 9/7/2011 10:45:42 PM

Jorgen Grahn <grahn+nntp@snipabacken.se> 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 me@student.foo.edu", "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) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21474) 9/8/2011 12:40:40 AM

On Wed, 07 Sep 2011 14:04:20 -0700, Harald van Dijk wrote:
> On Sep 7, 10:54 pm, nathan <spamt...@trashcan.invalid> 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
0
Reply spamtrap6468 (12) 9/8/2011 5:41:37 PM

On Sep 7, 2:04=C2=A0pm, Harald van D=C4=B3k <true...@gmail.com> wrote:
> On Sep 7, 10:54=C2=A0pm, nathan <spamt...@trashcan.invalid> 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
0
Reply cdalten (976) 9/8/2011 6:23:37 PM

On Sep 8, 8:23=C2=A0pm, Chad <cdal...@gmail.com> wrote:
> On Sep 7, 2:04=C2=A0pm, Harald van D=C4=B3k <true...@gmail.com> wrote:
> > On Sep 7, 10:54=C2=A0pm, nathan <spamt...@trashcan.invalid> 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".
0
Reply truedfx (1926) 9/8/2011 7:07:38 PM

Chad <cdalten@gmail.com> writes:
> On Sep 7, 2:04 pm, Harald van Dijk <true...@gmail.com> wrote:
>> On Sep 7, 10:54 pm, nathan <spamt...@trashcan.invalid> 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) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21474) 9/8/2011 7:10:19 PM

nathan <spamtrap@trashcan.invalid> 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) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21474) 9/8/2011 7:17:48 PM

nathan <spamtrap@trashcan.invalid> writes:

> On Wed, 07 Sep 2011 14:04:20 -0700, Harald van Dijk wrote:
>> On Sep 7, 10:54 pm, nathan <spamt...@trashcan.invalid> 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.
0
Reply ben.usenet (6515) 9/8/2011 7:41:27 PM

Keith Thompson <kst-u@mib.org> writes:

> nathan <spamtrap@trashcan.invalid> 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.
0
Reply ben.usenet (6515) 9/9/2011 12:09:13 AM

On 09/08/2011 02:23 PM, Chad wrote:
> On Sep 7, 2:04 pm, Harald van Dijk <true...@gmail.com> wrote:
>> On Sep 7, 10:54 pm, nathan <spamt...@trashcan.invalid> 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
0
Reply jameskuyper (5159) 9/9/2011 2:43:45 AM

On Thu, 2011-09-08, Keith Thompson wrote:
> Jorgen Grahn <grahn+nntp@snipabacken.se> 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 me@student.foo.edu", "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   .
0
Reply nntp24 (1559) 9/9/2011 9:25:20 AM

On Thu, 2011-09-08, Keith Thompson wrote:
> nathan <spamtrap@trashcan.invalid> 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   .
0
Reply nntp24 (1559) 9/9/2011 9:38:19 AM

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
0
Reply jameskuyper (5159) 9/9/2011 12:36:51 PM

Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> nathan <spamtrap@trashcan.invalid> 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) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21474) 9/9/2011 6:04:59 PM

Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> Keith Thompson <kst-u@mib.org> writes:
>
>> nathan <spamtrap@trashcan.invalid> 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.
0
Reply txr1 (1213) 1/24/2012 8:38:46 PM

17 Replies
34 Views

(page loaded in 0.191 seconds)

Similiar Articles:


















7/30/2012 1:21:44 AM


Reply: