Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > invoke function without declaration

Reply
Thread Tools

invoke function without declaration

 
 
Peter Nilsson
Guest
Posts: n/a
 
      11-17-2011
Keith Thompson <ks...@mib.org> wrote:
> Acid Washed China Blue Jeans <chine.b...@yahoo.com> writes:
> > Stanley Rice <hecong...@gmail.com> wrote:
> > >
> > > #include <stdio.h>
> > > void my_print(float a, int b)
> > > {
> > > * * printf("%f\t%d\n", a, b);
> > > }
> > >
> > > All three function are defined external without declaration in
> > > file main.c. But why the first two works well, but the last one
> > > fails? Is it undefined in ISO C?

> >
> > If you don't declare a function f, it is assumed to be
> > * * * * int f()
> > which passes all arguments with var-args rules.

>
> Not exactly, if by "var-args rules" you mean as if calling a variadic
> function (one with ", ..." in its declaration).


If they meant default argument promotions are applied to all
arguments,
then that _is_ how they're passed.

> Under C90 rules, the implicit declaration is for a function that
> returns int with a fixed number of parameters corresponding to the
> promoted types of the actual arguments in the call.


No, the implicit declaration is simply int f(), i.e. a function
returning int with an unspecified number of parameters.

>*So for
>
> * * my_print(2.0, a);
>
> the implicit declaration is
>
> * * int my_print(double, int);


No, it's int my_print(). [Which, BTW, isn't compatible with the
definition
in the OP's post above.]

> *not*
>
> * * int my_print(...);
>
> (which isn't even a valid declaration; variadic functions must have
> at least one non-variadic parameter).


True. But to demonstrate that there are no implicit parameters in the
implicit declaration consider...

#include <stdio.h>

int main(void)
{
int foo();
int i = 42;
int *ip = &i;
const int *cip = &i;

foo(ip);
foo(cip);

return 0;
}

int foo(int *cip)
{
printf("%d\n", *cip);
return 0;
}

If the first call to foo imposed an implicit declaration with fixed
parameters based on the promoted argument type, then the second call
to foo() would violate a constraint. It doesn't under C90, and
wouldn't under C99 if foo had been declared int foo() prior to
calling.

--
Peter
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      11-17-2011
Peter Nilsson <> writes:
> Keith Thompson <ks...@mib.org> wrote:
>> Acid Washed China Blue Jeans <chine.b...@yahoo.com> writes:
>> > Stanley Rice <hecong...@gmail.com> wrote:
>> > >
>> > > #include <stdio.h>
>> > > void my_print(float a, int b)
>> > > {
>> > > Â* Â* printf("%f\t%d\n", a, b);
>> > > }
>> > >
>> > > All three function are defined external without declaration in
>> > > file main.c. But why the first two works well, but the last one
>> > > fails? Is it undefined in ISO C?
>> >
>> > If you don't declare a function f, it is assumed to be
>> > Â* Â* Â* Â* int f()
>> > which passes all arguments with var-args rules.

>>
>> Not exactly, if by "var-args rules" you mean as if calling a variadic
>> function (one with ", ..." in its declaration).

>
> If they meant default argument promotions are applied to all
> arguments,
> then that _is_ how they're passed.


Yes and no. The default argument promotions are applied in the
same way; the calling convention may be quite different. That's why
calling a variadic function with no visible prototype has undefined
behavior, even in C90. (I still don't know what the previous poster
meant by "var-args rules".

>> Under C90 rules, the implicit declaration is for a function that
>> returns int with a fixed number of parameters corresponding to the
>> promoted types of the actual arguments in the call.

>
> No, the implicit declaration is simply int f(), i.e. a function
> returning int with an unspecified number of parameters.


You're right, thanks for the correction.

C90 6.3.2.2 says:

If the expression that precedes the parenthesized argument list
in a function call consists solely of an identifier, and if
no declaration is visible for this identifier, the identifier
is implicitly declared exactly as if, in the innermost block
containing the function call, the declaration

extern int identifier () ;

appeared.

(The effect of the nonexistent rule that I described would be similar to
the actual rule in the case of a single call.)

[snip]

--
Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      11-17-2011
On 11/16/2011 07:51 PM, Peter Nilsson wrote:
> Keith Thompson <ks...@mib.org> wrote:
>> Acid Washed China Blue Jeans <chine.b...@yahoo.com> writes:
>>> Stanley Rice <hecong...@gmail.com> wrote:
>>>>
>>>> #include <stdio.h>
>>>> void my_print(float a, int b)
>>>> {
>>>> � � printf("%f\t%d\n", a, b);
>>>> }
>>>>
>>>> All three function are defined external without declaration in
>>>> file main.c. But why the first two works well, but the last one
>>>> fails? Is it undefined in ISO C?
>>>
>>> If you don't declare a function f, it is assumed to be
>>> � � � � int f()
>>> which passes all arguments with var-args rules.

>>
>> Not exactly, if by "var-args rules" you mean as if calling a variadic
>> function (one with ", ..." in its declaration).

>
> If they meant default argument promotions are applied to all
> arguments,
> then that _is_ how they're passed.


It's more than just the argument promotions. Variadic functions are
allowed to use an ABI that is incompatible with that used by
non-variadic functions, even when they take arguments of the same
promoted type:

"For two function types to be compatible, ... the parameter type lists,
if both are present, shall agree ... in use of the ellipsis terminator.
.... If one type has a parameter type list and the other type is
specified by a function declarator that is not part of a function
definition and that contains an empty identifier list, the parameter
list shall not have an ellipsis terminator ..." (6.7.5.3p15).

Consider the following code:

define.c:
int foo(char *format, ...)
{
// Definition of f()
}

int bar(
char *format,
int i,
double d
)
{
}

main.c:
int foo();
int bar(char *, ...);

int main(int argc, char *argv[])
{
short s;
float f;
// Set things up

int a = foo(argv[1], s, f);
int b = bar(argv[2], s, f);
return 0;
}

The call to f() has undefined behavior because of 6.5.2.2p6: "... If the
expression that denotes the called function has a type that does not
include a prototype, ... [and] the function is defined with a type that
includes a prototype, and ... the prototype ends with an ellipsis (,
....) ... the behavior is undefined. ..."

In addition, both calls have undefined behavior because of 6.5.2.2p9:
"If the function is defined with a type that is not compatible with the
type (of the expression) pointed to by the expression that denotes the
called function, the behavior is undefined."
--
James Kuyper
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
type declaration in declaration of a parameter or return type of a function Luca Forlizzi C Programming 4 11-14-2010 09:30 PM
Can a static function declaration conflict with a non-static declaration? nospam_timur@tabi.org C Programming 4 12-12-2006 10:26 PM
maxplusII error: a deferred constant declaration without a full declaration is not supported Noah VHDL 5 04-07-2006 02:34 PM
Variable declaration taken as a function pointer declaration Bolin C++ 4 12-02-2005 05:28 PM
Function declaration in class declaration Ovidesvideo C++ 4 12-10-2004 06:36 PM



Advertisments