int func() v/s int func(void)

V

Vinko Vrsalovic

Hello,

I read a couple of posts ago that these are not equivalent, and that
the former means 'no arguments specified' and that calling for
instance func(3,"THREE",&myint) is legal.

What's the intended use of that way of declaring functions?

Thanks,
V.
 
M

Mike Wahler

Re: int func() v/s int func(void)

(If the text of your subject is intended as part of
your message, put it in your message. Not everyone's
newsreader shows the subject and body simultaneously,
in which case context is lost.)
Hello,

I read a couple of posts ago that these are not equivalent,
Correct.

and that
the former means 'no arguments specified'

Correct. (void) means specifically 'no arguments'.
and that calling for
instance func(3,"THREE",&myint) is legal.

It's 'legal' but might not 'work' (could produce undefined
behavior if not used correctly -- i.e. the function must
be written to handle those arguments).
What's the intended use of that way of declaring functions?

To write fragile code. IOW Don't Do That. It's an
anachronism from the days before prototypes were
added to C. (It's been kept so that old code will
still compile). Prototypes help you create correct
code, by enabling the compiler to do better error
checking. Use them. Always.


-Mike
 
J

Jens.Toerring

Please put what you're talking about into the body of your mail,
subject lines get ofter truncated by the news reader, making what
you ask about hard or even impossible to understand...

Subject: int func() v/s int func(void)
I read a couple of posts ago that these are not equivalent, and that
the former means 'no arguments specified' and that calling for
instance func(3,"THREE",&myint) is legal.
What's the intended use of that way of declaring functions?

It keeps the compiler from checking if you use the function with a well-
defined number of arguments and types. One "intended" use I can think of
is for pre-ANSI programs (written before about 1989) were you didn't had
function prototypes but which you still want modern compilers to be able
to compile. Another possible use is for declaration of function pointers
in plug-in systems where the number of arguments isn't known at compile
time but where e.g. libraries can be loaded while the program is already
running and you have methods to determine how many (or which) arguments
that function accepts (and then call the function accordingly). E.g. you
may have (non-standard and probably system-specific) functions called
pointer_to_func() and required_arg_count() to be used like this

int ( *to_be_loded )( ); /* arguments unspecified ! */
int num_args;
int result;

to_be_loaded = pointer_to_func( "name_of_function_to_be_loaded" );
num_args = required_arg_count( "name_of_function_to_be_loaded" );

if ( num_args == 0 )
result = to_be_loaded();
else if ( num_args == 1 )
result = to_be_loaded( 42 );
else
{
fprintf( stderr, "Too many arguments required\n" );
exit( EXIT_FAILURE );
}
Regards, Jens
 
E

Eric Sosman

Vinko said:
Hello,

I read a couple of posts ago that these are not equivalent, and that
the former means 'no arguments specified' and that calling for
instance func(3,"THREE",&myint) is legal.

What's the intended use of that way of declaring functions?

It's a leftover from the early development of C,
retained so code written prior to the creation of the
ANSI Standard had a hope of continuing to work correctly.

Old-time ("K&R") C had no function prototypes; all you
could say about a function defined "elsewhere" is that it
returned such-and-such a type. You could not describe the
number and types of the arguments except in the actual
function definition, which you did like this:

int func(a, b, c)
int a;
char *b;
int *c;
{
/* do stuff */
return 42;
}

.... and in some other module you'd declare it as

int func();
or
extern int func();

.... so no information about the arguments was given in the
declaration.

ANSI C swiped an idea from C++ to allow much more detailed
specification of functions; the idea was a good one, and all
new (i.e., for the last ten or twelve years) should use the
newer form. Still, the old form is kept around in the name of
backwards compatibility. (A name not to be trifled with, I might
add: C has been Standard-ized for less than half its life, and
quite a lot of code from its adolescent years is still around.)
 
S

sushant

in the declaration int func( ) means that u can pass any type and
number of arguments in the function func() which has the return type
int . but the declaration int func(void) means that u dont have to pass
any arguments in that function . this is the way C89 works but in C99
the former declartion and latter both are same ...
 
J

Jonathan Burd

Vinko said:
Hello,

I read a couple of posts ago that these are not equivalent, and that
the former means 'no arguments specified' and that calling for
instance func(3,"THREE",&myint) is legal.

What's the intended use of that way of declaring functions?

Thanks,
V.

Use ``int foo(void)" in your header files when you want to tell
the compiler explicitly that this function *does not* take any
arguments. ``int foo()" would allow it to use any number
of arguments. A good compiler would also warn you about this
(Intel's compiler does).

Regards,
Jonathan.
 
V

Villy Kruse

On Thu, 20 Jan 2005 20:36:26 -0500,



In GNU and other open source for unix you often see something like:


#if USE_ANSI_PROTOTYPE
int func (int a, int b);
#else
int func ();
#endif

int func (a, b)
int a;
int b;
{
...
}

The conditional compilation of the prototype can easily be implelemted
using a macro, so it doesn't look to desturbing visualy. It took a very
long time before all C compilers on unix systems were ANSI capable,
especialy for systems where the manufacturer stopped upgrading their
unix implementations. I beleive that most C compilers for MS-DOS were
ANSI or mostly ANSI from the beginning.
ANSI C swiped an idea from C++ to allow much more detailed
specification of functions; the idea was a good one, and all
new (i.e., for the last ten or twelve years) should use the
newer form. Still, the old form is kept around in the name of
backwards compatibility. (A name not to be trifled with, I might
add: C has been Standard-ized for less than half its life, and
quite a lot of code from its adolescent years is still around.)

If I'm not mistaken, in C++ func() means the same as func(void) would
mean in the C language. C++ at the time didn't have any legacy code to
consider.


Villy
 
N

Nejat AYDIN

sushant said:
in the declaration int func( ) means that u can pass any type and
number of arguments in the function func() which has the return type
int . but the declaration int func(void) means that u dont have to pass
any arguments in that function .

The declaration "int func(void)" means you *cannot* pass any argument
to that function.
this is the way C89 works but in C99
the former declartion and latter both are same ...

No. They are *not* same in C99 either.
 
E

Eric Sosman

Villy said:
In GNU and other open source for unix you often see something like:


#if USE_ANSI_PROTOTYPE
int func (int a, int b);
#else
int func ();
#endif

int func (a, b)
int a;
int b;
{
...
}

Despite its apparent simplicity, this approach can be
difficult to use correctly. It's fine if all the arguments
are `int' (as in your example) or `double' or pointers or
structs or unions -- but if they're `char' or `unsigned short'
or `time_t' or ... The problem is that these types may be
subject to the default argument promotions when passed to a
K&R function, and you don't know at coding time whether they're
promotable, nor to what.

As a concrete example, try writing a prototype for

enum Cubs { TINKER, EVERS, CHANCE };
double play(x)
enum Cubs x;
{...}

To write the prototype, you need to discover what type
an `enum Cubs' argument will promote to. Since the compiler
can choose any integer type at all to represent `enum Cubs'
and since the promotion rules for the integer types are, to
some extent, implementation-dependent (e.g., `unsigned short'
promotes to `int' on some systems, `unsigned int' on others),
you find yourself in the uncomfortable position of trying to
out-guess every compiler that will ever process the code.

The upshot is that the only declaration for play()
you can be utterly confident in is

double play();

.... which loses, er, "some" of the benefits of prototypes.
Anything else risks lying to the compiler -- and we all
know what happens, sooner or later, when you lie to the
compiler.
 
C

CBFalconer

Eric said:
.... snip ...

As a concrete example, try writing a prototype for

enum Cubs { TINKER, EVERS, CHANCE };
double play(x)
enum Cubs x;
{...}

To write the prototype, you need to discover what type
an `enum Cubs' argument will promote to. Since the compiler
can choose any integer type at all to represent `enum Cubs'
and since the promotion rules for the integer types are, to
some extent, implementation-dependent (e.g., `unsigned short'
promotes to `int' on some systems, `unsigned int' on others),
you find yourself in the uncomfortable position of trying to
out-guess every compiler that will ever process the code.

Why? Why can't we just write the prototype as:

double play(enum Cubs x);
and then
double play(enum Cubs x)
{
int retval = 0;

switch (x) {
case TINKER: snag();
if (caughtfly) retval++;
break;
case EVERS: touchnthrow();
if (intime2) retval++;
break;
case CHANCE: stretchntouch();
if (intime1) retval++;
break;
default: error();
}
return retval;
}

and I see no need to outguess or lie to the compiler.
 
K

Keith Thompson

Jonathan Burd said:
Use ``int foo(void)" in your header files when you want to tell
the compiler explicitly that this function *does not* take any
arguments. ``int foo()" would allow it to use any number
of arguments. A good compiler would also warn you about this
(Intel's compiler does).

In either case, a call must pass the number and types of arguments
consistent with the definition of foo(). The difference between the
declarations "int foo(void);" and "int foo();" is that the latter
doesn't let the compiler diagnose argument errors; it makes a call
with the wrong number of arguments undefined behavior rather than an
error requiring a compile-time diagnostic.
 
E

Eric Sosman

CBFalconer said:
Eric Sosman wrote:

... snip ...



Why? Why can't we just write the prototype as:

double play(enum Cubs x);

For the same reason that the prototype for
`void func(f) float f; {...}' is not `void func(float)'
but `void func(double)'.
 
V

Vinko Vrsalovic

Please put what you're talking about into the body of your mail,
subject lines get ofter truncated by the news reader, making what
you ask about hard or even impossible to understand...

Ok, will do. Thanks everyone.
[...]
to compile. Another possible use is for declaration of function pointers
in plug-in systems where the number of arguments isn't known at compile
time but where e.g. libraries can be loaded while the program is already
running and you have methods to determine how many (or which) arguments
that function accepts (and then call the function accordingly). E.g. you
may have (non-standard and probably system-specific) functions called
pointer_to_func() and required_arg_count() to be used like this

But from all the other answers I'd say this is more a side-effect than
an intended use. Anyhow, an interesting side-effect :)

Regards,
V.
 
C

Chris Torek

Eric said:
... snip ...
[more snippage]

Why? Why can't we just write the prototype as:

double play(enum Cubs x);
and then
double play(enum Cubs x)
{
[code snipped]

You can indeed write that. Moreover, you *should* write that, as
long as your compiler is not three decades old now. :) But you
have sidestepped the problem that Eric Sosman was describing, which
is:

"come up with a way to write a prototype declaration for
this function defined with an old-style, rather than modern
prototype-style, definition"

(which problem in turn comes up when trying to write code that
compiles with ancient C compilers -- to which the best answer is
now: "stop using that ancient C compiler". :) )

Seriously, it used to be important to write C code that could
compile on pre-1989-Standard C compilers. It also used to be 1991.
 
V

Villy Kruse

Despite its apparent simplicity, this approach can be
difficult to use correctly. It's fine if all the arguments
are `int' (as in your example) or `double' or pointers or

which they also are where this is done in real programs.



Villy
 

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
474,159
Messages
2,570,879
Members
47,414
Latest member
GayleWedel

Latest Threads

Top