overloaded functions in C

K

Keith Thompson

Ari Lukumies said:
Since when has C adopted overloaded functions? You must be talking
about C++.

No, he's talking about the language recognized by his lcc-win32
compiler. See comp.compilers.lcc for more information.
 
S

S.Tobias

What's the best way to implement an overloaded function in C? For
instance if you want to have generic print function for various
structures, my implementation would be with a case statement:
void print_structs(void * struct_argument, enum struct_type stype)
{
switch(stype) {
case STRUCT_TYPE_1:
struct type1 * p = (struct type1 *) struct_argument;
printf("type1.field1: %d\n", type1.field1);
case STRUCT_TYPE_2:
...
}
return;
}
One thing I don't like about this is that, you must encode type
information
in an enum. I don't like this because I don't prefer encoding
user-defined aspects into code in general. Is there a better way of
doing this?

See my second answer to Jacob Navia (it's six levels deep).
I have written a system of struct types, in which the type and its
methods are effectively encoded into the object. This way you can
have a single generic `print_structs()' and other functions, which don't
know the type they receive (therefore don't implement anything),
but still can call the right operation (method) on all objects that
"derive" from `PolymorphicBase' (the resolution is made run-time).
The implementation of methods can be hidden as `static' functions
in each file that defines particular "class".

Try to read it, if you have questions - ask.

A few more notes:

All types must include `struct PolymorphicBase' as the first
member. This might not work with other libraries which have
similar requirement.

If PolymorphicBase contains more members, it'll be waste of space
if all objects that belong to the same "class" carry the same
information. It would be better if PolymorphicBase was a static
object defined for each "class" (I think it could be even initialized
statically), and that each `struct TypeN' contained a pointer
to it as their first member.

The argument of `print_structs()' is `void*'. I thought about
`PolymorphicBase*' too, but then each pointer to `TypeN' would have
to be cast to `PolymorphicBase*', and nothing would be gained.
With `void*' you don't have to cast anything; it'll be UB
if you pass anything other than `TypeN' (or `PolymorphicBase'
itself).

The whole system might not prove flexible in the end.
This is C, not C++.
 
P

Peter Shaggy Haywood

Groovy hepcat jacob navia was jivin' on Thu, 09 Jun 2005 22:06:31
+0200 in comp.lang.c.
Re: overloaded functions in C's a cool scene! Dig it!
You misunderstand overloaded functions.

I don't think he does. I think he understands better than you do
that overloaded functions break standard compliance.
suppose:

int overloaded fn(Mytype *arg);
int overloaded fn(MyOtherType *arg);

overloaded is in user name space. Hence you break standard
compliance.
They are *not* the same object of course. They are TWO
different functions, that's the point!

----------------------------------------------------------------------
6.2.1 Scopes of identifiers
....
2 ... Different entities designated by the same identifier either have
different scopes, or are in different name spaces. ...
----------------------------------------------------------------------

This means that an identifier cannot designate multiple entities
within the same scope and name space. Thus, overloading is effectively
disallowed.
The user has the facility of calling those two objects
with the same name with different argument signatures.

Yes, we know what overloading is. But it is not allowed in C.
Someone pointed out that you could emit a diagnostic and compile it.
If that's what you do then that's fine. Then you can claim your
compiler is a standard conforming C compiler. But if it does not emit
a diagnostic when encountering overloaded functions, then it is not a
C compiler.
To stay within the standard, the overloaded function sqrt
refers to 3 different functions:

sqrt is not an overloaded function. It is, if tgmath.h is included,
a macro that uses some method to determine which of several functions
to call. We usually call this "compiler magic" because we, the users,
are not concerned with how this works. For all we know and care it
could be magic. (It doesn't require "compiler magic" to include
function overloading either. This could probably be implemented using
__typeof - which *is* allowed as an extention as it doesn't break
standard conformance - to determine which function to call. Or some
other incantations may be possible to achieve the desired ends. In any
case, the users are not supposed to know or care how. That is an
implementation detail.)
sqrtl(long double), sqrt(double) and sqrt(float).

This overloading doesn't mean that there is ONE sqrt function
but three of course.

No. It doesn't mean any such thing. It means there is one sqrt macro
which calls one of several functions, depending on the type of its
argument.
My implementation will not accept:

int overloaded fn(Mytype *arg) {... }
int overloaded fn(Mytype *arg) {... }

because THAT would be a redefinition of the same object, as the
standard specifies!

That is not at issue.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
J

john_bode

Hi,

What's the best way to implement an overloaded function in C?

Use C++.

Strictly speaking, you can't implement overloaded functions in C; the
language simply doesn't support the concept. As the flamefest with
navia demonstrates, you can find the odd *compiler* that supports them
as an extension, but that's not the same thing as doing it "in C".

There are a number of ways to fake it. Yours is one. Here's another
that's ugly, prone to error, not terribly extensible, and really not
worth the effort:

#include <stdio.h>
#include <stdlib.h>

#define foo(x,y) foo_ ## x (y)

void foo_int(int x)
{
printf("x = %d\n", x);
}

void foo_double(double x)
{
printf("x = %f\n", x);
}

int main(int argc, char *argv[])
{
printf("Hello, world!\n");
foo(int, 1);
foo(double, 3.14159);
// What's the point, right?
return EXIT_SUCCESS;
}


If it's a feature you *really* need, implement that portion in C++ (and
be aware of compatibility issues).
 
L

Lawrence Kirby

Groovy hepcat jacob navia was jivin' on Thu, 09 Jun 2005 22:06:31
+0200 in comp.lang.c.
Re: overloaded functions in C's a cool scene! Dig it!


I don't think he does. I think he understands better than you do
that overloaded functions break standard compliance.

I seems to have missed Jacob's reply on this.

Of course this is a syntax error as far as standard C is concerned due to
the extraneous overloaded identifier. Inless there is a macro definition
for it that expands to something appropriate a conforming implementation
is required to generate a diagnostic for the syntax error. However it
isn't obvious what something appropriate might be. If the macro expanded
to nothing and you got in effect

int fn(Mytype *arg);
int fn(MyOtherType *arg);

the constraint 6.7p4 I quoted above kicks in. According to the definition
of the C language these DO refer to the same function and they have
incompatible types. In a language that supported function overloading
using this syntax they would refer to different functions but standard C
is not such a language and a diagnostic is required for this and similar
code from a conforming implementation.

A conforming implementation can extend the language in areas that the
standard leaves undefined, and provide specific behaviour in areas the
standard makes unspecified or implementation-defined. It cannot alter the
syntax of the language (*) or ignore existing constraints.

* - there is leeway to add identifers in the implementation's
namespace which can be defined as macros because the effect of the
expansion is not visible, e.g. they might expand to nothing.
overloaded is in user name space. Hence you break standard
compliance.

But only in a language that is not C and violates the rules of the C
language. That's the point.


Lawrence
 

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,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top