Why would anyone do this?

B

Blue Ocean

Hey all, I'm a newbie and just learning C. I've been teaching it to
myself since I got home from school for the summer. I've also been
reading some code and I've been seeing a lot of this:

#define FDECL(functionname,params) functionname(params)

And then declarations like this (from include/extern.h, nethack):

E int NDECL(dojump);
E int FDECL(jump, (int));
E int NDECL(number_leashed);
E void FDECL(o_unleash, (struct obj *));
E void FDECL(m_unleash, (struct monst *,BOOLEAN_P));
E void NDECL(unleash_all);
E boolean NDECL(next_to_u);

etc.

Why? Is there any compelling reason not to type out the prototype?
This doesn't even save characters. Am I missing something?

Thanks in advance for any advice.

James
 
B

Ben Pfaff

#define FDECL(functionname,params) functionname(params)

And then declarations like this (from include/extern.h, nethack):

E int NDECL(dojump);

Presumably this is a dodge for old compilers that don't support
prototypes.
 
U

Ulrich Eckhardt

Blue said:
#define FDECL(functionname,params) functionname(params)

And then declarations like this (from include/extern.h, nethack):

E int NDECL(dojump);
E int FDECL(jump, (int));
E int NDECL(number_leashed);
E void FDECL(o_unleash, (struct obj *));
E void FDECL(m_unleash, (struct monst *,BOOLEAN_P));
E void NDECL(unleash_all);
E boolean NDECL(next_to_u);

Hmmm, half of these are NDECL, not FDECL!
Why? Is there any compelling reason not to type out the prototype?
This doesn't even save characters. Am I missing something?

Nethack is probably one of the most widely ported programs. As such, it had
to deal with various compilers, most of which are - by current standards -
broken and/or obsolete. Take a look at all the files of Nethack, I'm sure
you will find a definition for a compiler that does not resolve to a
prototype that you would have written.

I can't properly parse what you wrote, but it somehow reminds me of the old
way to write a function. It was
int foo( param)
float param
{ return 667; }

instead of
int foo( float param)
{ return 42; }

In short: Nethack is not the right source for learning C.

Uli
 
D

Dan Pop

In said:
Hey all, I'm a newbie and just learning C. I've been teaching it to
myself since I got home from school for the summer. I've also been
reading some code and I've been seeing a lot of this:

#define FDECL(functionname,params) functionname(params)

And then declarations like this (from include/extern.h, nethack):

E int NDECL(dojump);
E int FDECL(jump, (int));
E int NDECL(number_leashed);
E void FDECL(o_unleash, (struct obj *));
E void FDECL(m_unleash, (struct monst *,BOOLEAN_P));
E void NDECL(unleash_all);
E boolean NDECL(next_to_u);

etc.

Why? Is there any compelling reason not to type out the prototype?
This doesn't even save characters. Am I missing something?

Yup, you're missing the fact that you're looking at an *old* application.
You're also missing the fact that, under certain circumstances, FDECL
may be defined like this:

#define FDECL(functionname,params) functionname()

The point is not to save typing, but to provide prototype function
declarations to compilers that understand them, while still keeping
pre-ANSI compilers happy. Some people believed that the above technique
is a great idea, others went for the more readable:

#ifndef __STDC__

int jump();
void o_unleash();
void m_unleash();

#else

int jump(int);
void o_unleash(struct obj *);
void m_unleash(struct monst *, BOOLEAN_P);

#endif

What is lost by the marginally higher maintenance overhead (each
function has to be declared twice) is more than won back by the
improved readability: the code actually looks like C code.

Using macros that mess with the C syntax is seldom a good idea.

Dan
 
D

Dan Pop

In said:
I can't properly parse what you wrote, but it somehow reminds me of the old
way to write a function. It was
int foo( param)
float param
{ return 667; }

Not really: each parameter declaration was terminated with a semicolon
and these declarations were typically aligned with the first line of the
function definition and the opening brace:

int main(argc, argv)
int argc; /* optional: undeclared parameters were int by default */
char **argv;
{
/* get the work done */
}

Note that even C99 supports this function definition syntax, but each
parameter must be explicitly declared (another instance of no implicit
int in C99).

Dan
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,745
Messages
2,569,485
Members
44,909
Latest member
DestinyKetoScam

Latest Threads

Top