overloaded functions in C

C

Chris Croughton

You misunderstand overloaded functions.
suppose:

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

They are *not* the same object of course. They are TWO
different functions, that's the point!

The user has the facility of calling those two objects
with the same name with different argument signatures.

To stay within the standard, the overloaded function sqrt
refers to 3 different functions:
sqrtl(long double), sqrt(double) and sqrt(float).

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

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!

Nor will it accept the standard-conforming program:

#include <stdio.h>

extern int overloaded(void);

int main(void)
{
printf("hello\n");
return 0;
}

So it isn't a C compiler.

Chris C
 
J

jacob navia

Chris said:
No, you did not, you implemented them in the user namespace.

No. You can *still* declare:

int overloaded = 78;

and it will compile without problems.

You can also write:
struct overloaded {
int a;
};

I have worked a lot to make that possible, and I am confident it
works. Remember: one of the conditions was to avoid any
new keywords, and I have respected that. Of course if there
is a construction where this could cause problems
I will fix it.

jacob
 
J

jacob navia

Chris said:
Well, if those were the names they'd be easy to remember but hard to
type correctly. But fsqrt and lsqrt are pretty easy to remember,

You forgot Chris. The correct name is sqrtf and sqrtl !!!!

You see?

NOT so easy!

jacob
 
J

jacob navia

CBFalconer said:
Instead of deliberately trolling with this you could have simply
said that this is a non-standard non-portable extension, available
in lcc-win32 for those who wish to fool with it. Is that so hard?
Then the clamor would probably be limited to pointing out the
insecurities it raises.

The internet is for exchanging ideas and viewpoints. I try
to avoid personal attacks and argument my views.

I respect people with other views as mine.
 
C

Chris Croughton

Well, if those were the names they'd be easy to remember but hard to
type correctly. But fsqrt and lsqrt are pretty easy to remember,

They are, of course, easy to misremember as well <g>. The names are
sqrtl, sqrtf etc.

(I've never used them, I don't write C99 because it isn't portable to
all compilers I'm likely to need to use...)

Chris C
 
K

Keith Thompson

jacob navia said:
What's the best way to implement an overloaded function in C?
[...]
lcc-win32 is a C compiler that implements overloaded functions.

When invoked as a C compiler, it does not implement overloaded
functions.

If it implements overloaded functions, it is not a C compiler.

(It's conceivable that a conforming C compiler could implement
overloaded functions. It would have to issue a diagnostic for any
code that violates a syntax rule or a constraint; once a diagnostic is
issued, the standard doesn't actually forbid the compiler to generate
an executable. But I don't believe that's how lcc-win32 operates.)

Jacob, others have already complained your response's lack of
topicality, the fact that there's another newsgroup in which lcc-win32
is topical, and the inappropriateness of posting advertisements here;
I won't add to that, other than to mention that the language
implemented by lcc-win32 is no more topical here than C++ or C# is.

But at the very least, you should have acknowledged that you haven't
actually addressed the OP's question. He asked about implementing an
overloaded function *in C*. lcc-win32's non-standard extension does
not do that.
 
J

jacob navia

Keith said:
(It's conceivable that a conforming C compiler could implement
overloaded functions. It would have to issue a diagnostic for any
code that violates a syntax rule or a constraint; once a diagnostic is
issued, the standard doesn't actually forbid the compiler to generate
an executable. But I don't believe that's how lcc-win32 operates.)

I will add a flag
-comp.lang.c

If in that mode I will issue:

Warning: overloaded function detected at mycode.c line 456

:)
 
E

Eric Sosman

jacob said:
Typical of you Eric:

Just polemic, no arguments, no nothing.

That's how I hope to be remembered. Ask anyone.
"A different language" ???

Absolutely. You'll note that my delusions on this
matter are shared by a few others; I have propagated my
heresies more successfuly than you have yours.
Questions for you:

1) Is "sqrt" an overloaded function or not?

It is not. It is an ordinary library function that
takes a `double' argument and returns a `double' value.
2) Isn't that defined in the C standard document?

Yes, in section 7.12.7.5. (You might want to re-
read that section, since your recollection of it seems
a bit shaky.)
3) What you thing about the definitions in tgmath.h?
("tg" stands for "Type Generic" math).

<tgmath.h> declares no functions (except indirectly,
by including <math.h> and <complex.h>).

<tgmath.h> defines macros -- including one named
sqrt -- that require "compiler magic" to implement. It
"overloads" macros, but does not overload functions.
3) Why shouldn't this feature be available to all?

(Did you forget a `++'?) Why not, indeed? But one
might equally ask why other things aren't available to all:
the compiler magic behind longjmp(), for example, which a
clever programmer might use to implement a less cumbersome
exception framework. Why not expose the machinery that
makes `sig_atomic_t' work? Or printf(), so the user can
define his own conversion specifiers on the fly?

The desirability of a feature does not equate to its
presence.
What do you have against this feature besides that
is an extension?

Nothing; where have I objected to it? What I object
to is your claim that this feature *is* in C -- which it
is not, in any user-accessible form.

I don't know what extensions and accretions and stuff
you've piled into Your Own Private Language -- I'm sure it's
been a labor of love, and I'm sure the result is probably
useful in some contexts. But I'm not going to advise people
to use `PIC $999,999.99' to format currency outputs just
because YOPL understands some COBOL. I'm not going to
suggest using unnamed struct and union elements, garbage
collection, `throw' and `catch', `ON ERROR PUT DATA', self-
modifying code, speculative evaluation, or whatever other
bits and pieces of possibly useful stuff YOPL has accreted.

Neither should you, not under the guise of "in C."
 
K

Keith Thompson

jacob navia said:
Extensions are a common feature of most C compilers
and systems. The standard sets a minimum language,
but all implementation implement extensions in one way or
another.

Is gcc in non pedantic mode not a C compiler any more?

No, it isn't.
And Microsoft with their __declspec(...) is no longer C?

Since __declspec is in the implementation's namespace, it might not be
a violation. I don't know the details, so I can't tell for sure.
Let's be realistic and discuss the issues here.

A user asked about how to implement overloaded functions because
he needs them, they are useful. Most languages have this feature
in one way or another, from C# to C++ passing through all OO
languages, etc.

No, a user asked about how to implement overloaded functions *in C*.

Suppose C++ didn't already exist. Suppose you had implemented a
compiler for a language very much like what we know as C++. Would
discussions of your language be topical here? Especially if your
language were implemented only on one platform, and you had no reason
to think that the original poster was using that platform?

Same question for C#, or Java, or any non-C language that bears some
resemblance to C.

[...]
Overloaded functions allow more flexibility in the implementation
and less impact in the memory space of the user.
[snip]

Nobody is arguing about whether overloaded functions are a good idea.
They just aren't C.

If you want to advocate adding function overloading to a future C
standard, you know where to find comp.std.c. Even if you did so here
in comp.lang.c, I wouldn't have too much of a problem with it.
Unfortunately, that's not what you're doing.
Have you anything against genericity? Should be eliminate tgmath
from the standard then?

No, I have nothing against genericity. I'm not particularly happy
that <tgmath.h> requires compiler support for function overloading but
doesn't make it available to users. I'd be glad to see this remedied
in a future standard.
 
K

Kenny McCormack

(e-mail address removed) (Kenny McCormack) writes:
[...]
"Asserting something 1,000 times does not, in and of itself, make it true."

Perhaps some day you'll learn that.

Most of us outgrew "nanny nanny boo boo, rubber and glue, bounces off of me
and sticks to you" by the time we were 12.
 
S

S.Tobias

jacob navia said:
S.Tobias wrote:
Using overloaded functions the switch disappears and you have:
void *overloaded print_structs(Type1 *p)
{ [snip]

void *overloaded print_structs(Type2 *p)
{ [snip]

"Polymorphic types"... can you explain?

Function overloading is merely a "syntactic sugar". If the OP wanted
that, he would probably have had:
void print_structs_Type1(Type1 *p);
void print_structs_Type2(Type1 *p);
which is not much more or less nuisance from declaring and invoking:
void print_structs(void *p, enum struct_type stype);
print_structs(pstruct, eType1);
etc.,
and he would complain he didn't like so many functions, how to have
only one.

Instead he had a *single* function, that handled many data types.
In his description he wrote he had a "generic print function", and
that's what he would probably like to stay with, since he only
wrote he didn't like to put implementation details into this
"generic function".

There's a huge difference between having many functions with the
same name, and a single function that can handle many types
of data.

What he probably wanted, and didn't know he wanted it, is the idea
of polymorphic type.

struct PolymorphicBase {
void (*print_myself)(struct PolymorphicBase*);
/*...*/
};

struct Type1 {
struct PolymorphicBase _pb;
/* ... Type1 data ... */
};

static
void printType1(struct PolymorphicBase *p_pb) {
struct Type1 *pT1 = (struct Type1*)p_pb;
printf("...", pT1->...);
}

void initType1(Type1 *pT1) {
pT1->_pb.print_myself = printType1;
/*...*/
}

void print_structs(void *generic) {
((struct PolymorphicBase*)generic)->print_myself(generic);
}

Each new TypeX defines its implementation in its own translation
unit, the implementation is hidden, and we have a single generic
function `print_structs'. Clean and dandy. Now we can build upon it:
typedef void (*generic_action_t)(void*);
generic_action_t tga[] = {print_structs, speak_structs, sing_structs,
play_structs, love_structs, hate_structs};
struct TypeN structN;
initTypeN(&structN);
tga[user_action_choice](&structN);


+++

By now I see thirty answers to your off-topic post,
and none (!) to the OP's problem. How helpful was that?
By the way, the C standard does have overloaded functions:
[snip]

So what? All operators are overloaded, too. So, what?
Why should this feature not be available to users?

It probably could. It could probably be even useful.
That's the whole point here.

The point is that you have brought it in an extremely
inapropriate way, hostile to the OP.


[ hurrah! finished! -- bed time... hrrr...]
 
M

Madhav

One way that I can think of in C is:

#include<stdio.h>

typedef enum {
INT=1,
FLOAT,
DOUBLE
}TYPES;

typedef union
{
int a;
float b;
double c;
}types;

int overloaded(int type, types );

int main(void)
{
types arg;

arg.b=20.33;
overloaded(FLOAT,arg);
arg.a=10;
overloaded(INT,arg);

return 0;
}

int overloaded(int type,types args)
{
switch(type)
{
case INT:
printf("Called with int argument=%d\n",args.a);
break;
case FLOAT:
printf("Called with float argument=%f\n",args.b);
break;
case DOUBLE:
printf("Called with double argument=%lf\n",args.c);
break;
}
}

for accepting variable number of arguments, we can use the stdarg.h .
That should be easy.
 
J

jacob navia

Chris said:
Nor will it accept the standard-conforming program:

#include <stdio.h>

extern int overloaded(void);

int main(void)
{
printf("hello\n");
return 0;
}

So it isn't a C compiler.

Chris C

That was yesterday Chris.
Today it accepts it... :)

I had started to implement overloaded function pointers
and there was an error in there.

Thanks for this bug report.
 
C

Chris Croughton

That was yesterday Chris.
Today it accepts it... :)

I had started to implement overloaded function pointers
and there was an error in there.

That wasn't a function pointer.
Thanks for this bug report.

How about operator (same problem, different error messages)?

Have you tested all other conformant syntax to make sure that it still
compiles correctly? That's the problem with extensions, unless they are
in the implementation namespace then they are very prone to errors.

And of course it still isn't "in C" as required by the OP, it's in
"Jacob Navia's C With Extensions" (which is not the same as "GNU C With
Extensions", "Microsoft C With Extensions" etc.).

Chris C
 
D

David Resnick

Hi,

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?

Thanks,
Bahadir

This whole thing has turned into a Jacob Navia flame war. I agree
with others that a "C" solution should not use extensions only
available
on his compiler. You could convert your code to C++ and only use
the overloading feature of that language and the rest of your code
could likely remain largely unchanged (some more casts, sizeof 'c'
has changed, some variable names might be keywords etc). I think
that is likely a better approach than using lcc-win32 if you
*really need* overloading.

If you want to do it in C, I don't think there is generically a better
way. You could more directly associate the type with the struct, for
example requiring that your structs have a field called "type" that
is an enum, and using a macro to call the function. Example (
code below not checked). Usual macro cavaets, don't say
PRINT_STRUCTS(foo++)...

#define PRINT_STRUCTS(foo) print_structs((foo), (foo)->type)

If you have a common way the structs are generated, the association
between struct and type could be established in just one
place, for example:

foo *make_foo(/* args for initialization*/)
{
foo *new_foo = malloc(sizeof *new_foo);
/* check malloc success */
foo->type = foo_struct;
/* ... fill in args ... */

return foo;
}

I don't know if that is better than what you are doing, but it
may be more coherent...

-David
 
J

jacob navia

Chris said:
That wasn't a function pointer.

yes, but in a function pointer you have
int overloaded (*foo)(int,double);

So it can be that operator is followed by a '('.
This introduced this error.
How about operator (same problem, different error messages)?
That was corrected too, with the correction yesterday.
Have you tested all other conformant syntax to make sure that it still
compiles correctly? That's the problem with extensions, unless they are
in the implementation namespace then they are very prone to errors.

It is only a problem if you do not introduce new keywords,
as the C standard specifies.
 
A

Ari Lukumies

jacob said:
You misunderstand overloaded functions.
suppose:

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

Since when has C adopted overloaded functions? You must be talking about
C++.

-atl-
 

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,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top