469,572 Members | 1,201 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,572 developers. It's quick & easy.

overloaded functions in C

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

Nov 14 '05 #1
44 2122
ba************@gmail.com wrote:
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

lcc-win32 is a C compiler that implements overloaded functions.
http://www.cs.virginia.edu/~lcc-win32

Please:

flames >/dev/null
Nov 14 '05 #2
jacob navia <ja***@jacob.remcomp.fr> wrote:
lcc-win32 is
Phenomenally off-topic here, and you _know_ this, damn you, navia!
Please:

flames >/dev/null


Please: off-topic advertisements to your own playground newsgroup.

Richard
Nov 14 '05 #3
jacob navia wrote:

lcc-win32 is a C compiler that implements overloaded functions.
If it implements overloaded functions, it is not a C
compiler.
Please:

flames >/dev/null


I have not objected to your self-promotion before; every
useful signal carries some noise. But this latest post is the
worst I have seen: it is a deliberate attempt to mislead. It is
not merely advertising, but false advertising.

I will send my future flames to /dev/null if you will send
your future nonsense there, too. Deal?

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 14 '05 #4
Eric Sosman wrote:
jacob navia wrote:
>

lcc-win32 is a C compiler that implements overloaded functions.

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

The ANSI C standard page 7:
A conforming implementation may have extensions (including additional
library functions), provided they do not alter the behavior of any
strictly conforming program.3)
And in the footnote 3 we have 3) This implies that a conforming implementation reserves no identifiers
other than those explicitly reserved in this International Standard.


I have respected in the implementation of overloaded functions both
points.

So, even if you do not like it, lcc-win32 is a C compiler.
Nov 14 '05 #5
Richard Bos wrote:

Phenomenally off-topic here, and you _know_ this, damn you, navia!


Since this newsgroup is too old to have a chart, this is your
personal appreciation. I beg to differ.

jacob
Nov 14 '05 #6
In article <42**********************@news.wanadoo.fr>,
jacob navia <ja***@jacob.remcomp.fr> wrote:
Richard Bos wrote:

Phenomenally off-topic here, and you _know_ this, damn you, navia!


Since this newsgroup is too old to have a chart, this is your
personal appreciation. I beg to differ.

jacob


Indeed. Well put.

I think that your (Jacob's) standard response to this kind of BS should be
to state:

"Asserting something 1,000 times does not, in and of itself, make it true."

Nov 14 '05 #7
On Thu, 09 Jun 2005 14:58:31 +0200, jacob navia wrote:

....
The ANSI C standard page 7:
>> A conforming implementation may have extensions (including additional
library functions), provided they do not alter the behavior of any
strictly conforming program.3) >>
And in the footnote 3 we have >> 3) This implies that a conforming implementation reserves no identifiers
other than those explicitly reserved in this International Standard. >>

I have respected in the implementation of overloaded functions both
points.


However these aren't the only requirements of a conforming implementation.
It must for example generate a diagnostic if the program contains a syntax
error or constraint violation. For example consider the constraint:

6.7p4 All declarations in the same scope that refer to the same object or
function shall specify compatible types.

Of course you can meet this requirement by generating diagnostics and
still compile the code, but it is usually easier (i.e. not to have to
explain diagnostics to your users) to support extensions like this in a
non-conforming mode.
So, even if you do not like it, lcc-win32 is a C compiler.


Most compilers can be invoked in various modes, some of which might be
conforming (or attempt to be) others not. So just saying that something is
a C compiler barely begins to tell the story.

Lawrence

Nov 14 '05 #8
Lawrence Kirby wrote:
Most compilers can be invoked in various modes, some of which might be
conforming (or attempt to be) others not. So just saying that something is
a C compiler barely begins to tell the story.


If you invoke lcc-win32 with the flag

-ansic

it will not accept any overloaded functions.
All other extensions aren't recognized either (operator
overloading and default function arguments).
Nov 14 '05 #9
On Thu, 09 Jun 2005 13:24:08 +0200, jacob navia
<ja***@jacob.remcomp.fr> wrote:
ba************@gmail.com wrote:
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
lcc-win32 is a C compiler that implements overloaded functions.


But not in C. In some vaguely C-like language, possibly.
http://www.cs.virginia.edu/~lcc-win32

Please:

flames >/dev/null


Stop your false advertising, then.

Chris C
Nov 14 '05 #10
On Thu, 09 Jun 2005 17:59:06 +0200, jacob navia
<ja***@jacob.remcomp.fr> wrote:
Lawrence Kirby wrote:
Most compilers can be invoked in various modes, some of which might be
conforming (or attempt to be) others not. So just saying that something is
a C compiler barely begins to tell the story.
If you invoke lcc-win32 with the flag

-ansic

it will not accept any overloaded functions.
All other extensions aren't recognized either (operator
overloading and default function arguments).


But in that mode it won't do what you claimed for it:
lcc-win32 is a C compiler that implements overloaded functions.


Either it is in a mode where it accepts overloaded functions, in which
case it is not a C compiler in that mode, or it is in -ansic mode where
it doesn't accept overloaded functions (in that mode it may or may not
be a C compiler for other reasons).

So saying "lcc-win32 is a C compiler that implements overloaded
functions" is false. It is a compiler which will compiler C /or/ this
other language with overloaded functions, but it will not do both with
the same program.

Since it is also pushing your own product, it is advertising.

The combination is "false advertising", which may be a crime in your
country (it is in others)...

Chris C
Nov 14 '05 #11
Chris Croughton wrote:
Either it is in a mode where it accepts overloaded functions, in which
case it is not a C compiler in that mode,

Chris C


Wrong. Please read the standard and see in page 7:
A conforming implementation may have extensions


Extensions are not forbidden, if implemented according to the
constraints that I followed.

The -ansic flag disallows any extensions, and all
functions not in the standard. No windows.h no
network, etc etc.

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?

And Microsoft with their __declspec(...) is no longer C?

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.

I understand C not as a freezed language that shuns any
improvement but as a language that should be as easy to
use as possible and that allows to construct modern software.

Overloaded functions allow more flexibility in the implementation
and less impact in the memory space of the user. Calling a
function
sqrt_for_long_doubles
sqrt_for_double
sqrt_for_float
just makes things more difficult to remember.

This is a plain truth, so much so, that the standard specifies
the overloaded function sqrt for all of those types.

That was a good idea, that I made available to the users of my
compiler system. Why the implementor should have something
that user's can't use? If the implementor uses them, they are
needed and the user have a right to use that too.

Calling all those three functions sqrt (as the standard header
tgmath defines) makes programming in C easier.

I just made that idea available to the users.

Let's stop the polemic and discuss the issues at hand. All of this
"I am holier than you" discussion is a waste of time.

Have you anything against genericity? Should be eliminate tgmath
from the standard then?

jacob
Nov 14 '05 #12
Lawrence Kirby wrote:

However these aren't the only requirements of a conforming implementation.
It must for example generate a diagnostic if the program contains a syntax
error or constraint violation. For example consider the constraint:

6.7p4 All declarations in the same scope that refer to the same object or
function shall specify compatible types.


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!

Nov 14 '05 #13
jacob navia wrote:
sqrtl(long double), sqrt(double) and sqrt(float).
Sorry that should have been sqrtl(long double), sqrt(double) and sqrtf(float).


forgot the 'f' in sqrt(float)
Nov 14 '05 #14
jacob navia wrote:
ba************@gmail.com wrote:

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:
.... snip ...

lcc-win32 is a C compiler that implements overloaded functions.
http://www.cs.virginia.edu/~lcc-win32


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.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #15


jacob navia wrote:
[...]
A user asked about how to implement overloaded functions because
he needs them, they are useful. [...]
The user asked, and I quote:
What's the best way to implement an overloaded function in C?


Look carefully at the end of the question. Squint your eyes,
and you might just be able to make out the requirement: "in C."
He didn't ask how to implement overloaded functions in Java or
Scheme or C++ or SmallTalk or in just any old language somebody
decides to suggest, he asked how to implement them "in C."

When you "answered" by suggesting he use a different language
(to wit, your own private language), you were unresponsive. When
you claimed that YOPL was in fact C, you were being untruthful.
Now, you're just being unpleasant.

--
Er*********@sun.com
Nov 14 '05 #16
jacob navia <ja***@jacob.remcomp.fr> wrote:
Eric Sosman wrote:
jacob navia wrote:
>
lcc-win32 is a C compiler that implements overloaded functions.

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


The ANSI C standard page 7: [snip quotes]
I have respected in the implementation of overloaded functions both
points. So, even if you do not like it, lcc-win32 is a C compiler.


1. Your compiler may be quite good and conforming (I don't know,
I haven't tried it, and it's not for me to judge anyway),
I think it is pretty clear that in this group particular
extensions are not topical. Otherwise valid topics would include
POSIX, Win32 API, __far pointers, __cdecl(export) declarations,
statement expressions, structured exceptions, __foos and __bars,
and many more in heaven and earth than are dreamt of in your
implementation.

2. You have not explained to the OP that C does not support
user defined function overloading, and in your implementation
it is an extension, and that it probably works _only_ in your
implementation. I don't think that inviting people to try
new language features in your product is bad by itself, but
I think that failing to mention that those features are
not portable - is.

3. All C++ compilers also support overloaded functions. So what?

4. OP asked a question how you *implement* overloaded functions (I
understand he meant the concept of overloaded functions).
In what way is your answer relevant?

5. Have you actually read the OP's article? Could you explain how
function overloading would solve his problem? Because from
what *I* have understood from his description, his needs are closer
to the concept of polymorphic types, rather than overloading.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #17
Eric Sosman wrote:

jacob navia wrote:
[...]
A user asked about how to implement overloaded functions because
he needs them, they are useful. [...]

The user asked, and I quote:

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

Look carefully at the end of the question. Squint your eyes,
and you might just be able to make out the requirement: "in C."
He didn't ask how to implement overloaded functions in Java or
Scheme or C++ or SmallTalk or in just any old language somebody
decides to suggest, he asked how to implement them "in C."

When you "answered" by suggesting he use a different language
(to wit, your own private language), you were unresponsive. When
you claimed that YOPL was in fact C, you were being untruthful.
Now, you're just being unpleasant.


Typical of you Eric:

Just polemic, no arguments, no nothing.
"A different language" ???

Questions for you:

1) Is "sqrt" an overloaded function or not?
2) Isn't that defined in the C standard document?
3) What you thing about the definitions in tgmath.h?
("tg" stands for "Type Generic" math).
3) Why shouldn't this feature be available to all?

What do you have against this feature besides that
is an extension?

Nov 14 '05 #18
S.Tobias wrote:
5. Have you actually read the OP's article? Could you explain how
function overloading would solve his problem? Because from
what *I* have understood from his description, his needs are closer
to the concept of polymorphic types, rather than overloading.


Using overloaded functions the switch disappears and you have:

void *overloaded print_structs(Type1 *p)
{
printf("Struct Type 1":\n");
...
}
void *overloaded print_structs(Type2 *p)
{
printf("Struct Type 2":\n");
...
}

etc.

"Polymorphic types"... can you explain?

By the way, the C standard does have overloaded functions:

sqrt(double)
sqrt(long double)
sqrt(float)

are the same as

sqrtl(long double)
sqrt(double)
sqrtf(float)

the "function" sqrt is overloaded to 3 different functions.
And this is 100% standard C.

Why should this feature not be available to users?

That's the whole point here.

jacob
Nov 14 '05 #19
On Thu, 09 Jun 2005 21:52:49 +0200, jacob navia
<ja***@jacob.remcomp.fr> wrote:
Chris Croughton wrote:
Either it is in a mode where it accepts overloaded functions, in which
case it is not a C compiler in that mode,

Chris C
Wrong. Please read the standard and see in page 7:
>> A conforming implementation may have extensions >>


Extensions are not forbidden, if implemented according to the
constraints that I followed.


No, you did not, you implemented them in the user namespace.
The -ansic flag disallows any extensions, and all
functions not in the standard. No windows.h no
network, etc etc.
Not much use then, if it can't use external libraries and headers --
which /are/ allowed by the standard.
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.
All? Well, perhaps you've checked every C compiler in existence.
Although extensions are necessary for some features of C99.
Is gcc in non pedantic mode not a C compiler any more?
Correct, it adds certain features (like asm) in the user namespace, thus
implementing a language almost, but not quite, C (indeed, with no
language specified the default is a language somewhere between C89 and
C99, with extra non-standard bits).
And Microsoft with their __declspec(...) is no longer C?
__declspec is in the implementation namespace, which is allowed by the
standard. Of course, they have had other inconsistencies as well...
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.
And the answer is "They don't exist in C". If you want them, use
another language (C++ is a standard, for instance).
I understand C not as a freezed language that shuns any
improvement but as a language that should be as easy to
use as possible and that allows to construct modern software.
It certainly does the latter. If you want "as easy to use as possible"
I suspect you want LOGO or a form of BASIC.
Overloaded functions allow more flexibility in the implementation
and less impact in the memory space of the user. Calling a
function
sqrt_for_long_doubles
sqrt_for_double
sqrt_for_float
just makes things more difficult to remember.
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,
particularly since they are consistent with the other maths functions'
naming. I would have liked to see dsqrt as a synonym for sqrt, just for
consistency, but I'm not too fussed about it.
This is a plain truth, so much so, that the standard specifies
the overloaded function sqrt for all of those types.
Only with the hideous tgmath.h extensions, which do indeed require
extensions (but not actually overloading, although they have that
effect).
That was a good idea, that I made available to the users of my
compiler system. Why the implementor should have something
that user's can't use? If the implementor uses them, they are
needed and the user have a right to use that too.
Indeed, I think that if they were going to allow it at all then it
should have been specified properly.

BUT IT WASN'T. That is the point, that no matter how much you want it
that feature IS NOT C.
Calling all those three functions sqrt (as the standard header
tgmath defines) makes programming in C easier.

I just made that idea available to the users.
And thereby created another language variant. It is not C, it is "C
with extensions".
Let's stop the polemic and discuss the issues at hand. All of this
"I am holier than you" discussion is a waste of time.
The issue is that a person asked whether overloaded functions are
available in C. The correct answer is simple, they are not. You,
however, attempted to mislead by pushing your almost-C compiler which
has them as extensions (and without pointing out that this is a
non-standard feature and is only available on one platform). That is
fraud,
Have you anything against genericity? Should be eliminate tgmath
from the standard then?


My preference is yes. It isn't needed (if you don't know what type you
want, your design is faulty, if it matters then you need to be able to
specify it). My next preference is that if they really think that
overloading is useful then it should be made generally available as a
standard feature.
Nov 14 '05 #20
Chris Croughton wrote:
On Thu, 09 Jun 2005 21:52:49 +0200, jacob navia
<ja***@jacob.remcomp.fr> wrote:

Chris Croughton wrote:
Either it is in a mode where it accepts overloaded functions, in which
case it is not a C compiler in that mode,

Chris C


Wrong. Please read the standard and see in page 7:
>>

A conforming implementation may have extensions
>>


Extensions are not forbidden, if implemented according to the
constraints that I followed.

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
Nov 14 '05 #21
Chris Croughton wrote:
On Thu, 09 Jun 2005 21:52:49 +0200, jacob navia
<ja***@jacob.remcomp.fr> wrote:
Overloaded functions allow more flexibility in the implementation
and less impact in the memory space of the user. Calling a
function
sqrt_for_long_doubles
sqrt_for_double
sqrt_for_float
just makes things more difficult to remember.

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
Nov 14 '05 #22
CBFalconer wrote:

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.
Nov 14 '05 #23
jacob navia <ja***@jacob.remcomp.fr> writes:
ba************@gmail.com wrote:
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #24
ga*****@yin.interaccess.com (Kenny McCormack) writes:
[...]
"Asserting something 1,000 times does not, in and of itself, make it true."


Perhaps some day you'll learn that.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #25
Keith Thompson wrote:
(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

:-)

Nov 14 '05 #26


jacob navia wrote:

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."

--
Er*********@sun.com

Nov 14 '05 #27
jacob navia <ja***@jacob.remcomp.fr> writes:
[...]
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #28
On Thu, 09 Jun 2005 22:06:31 +0200, jacob navia
<ja***@jacob.remcomp.fr> wrote:
Lawrence Kirby wrote:

However these aren't the only requirements of a conforming implementation.
It must for example generate a diagnostic if the program contains a syntax
error or constraint violation. For example consider the constraint:

6.7p4 All declarations in the same scope that refer to the same object or
function shall specify compatible types.


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
Nov 14 '05 #29
On Thu, 9 Jun 2005 21:45:15 +0100, Chris Croughton
<ch***@keristor.net> wrote:
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
Nov 14 '05 #30
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
ga*****@yin.interaccess.com (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.

Nov 14 '05 #31
jacob navia <ja***@jacob.remcomp.fr> wrote:
S.Tobias wrote:
5. Have you actually read the OP's article? Could you explain how
function overloading would solve his problem? Because from
what *I* have understood from his description, his needs are closer
to the concept of polymorphic types, rather than overloading.

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...]

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #32
Hi,
For this you need to design ur own parser or design a new compiler.

Nov 14 '05 #33
jacob navia <ja***@jacob.remcomp.fr> wrote:
Keith Thompson wrote:
(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


It would be better if you added that flag to yourself.

Richard
Nov 14 '05 #34
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.

Nov 14 '05 #35
Chris Croughton wrote:

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.
Nov 14 '05 #36
On Fri, 10 Jun 2005 09:36:25 +0200, jacob navia
<ja***@jacob.remcomp.fr> wrote:
Chris Croughton wrote:

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.
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
Nov 14 '05 #37
ba************@gmail.com wrote:
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

Nov 14 '05 #38
Chris Croughton wrote:
On Fri, 10 Jun 2005 09:36:25 +0200, jacob navia
<ja***@jacob.remcomp.fr> wrote:

Chris Croughton wrote:
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.
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.


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.
Thanks for this bug report.

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.
Nov 14 '05 #39
jacob navia wrote:
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-
--
A multiverse is figments of its own creations
Nov 14 '05 #40
Ari Lukumies <ar**********@gmail.com> writes:
jacob navia wrote:
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++.


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

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #41
ba************@gmail.com wrote:
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++.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #42
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!
Lawrence Kirby wrote:

However these aren't the only requirements of a conforming implementation.
It must for example generate a diagnostic if the program contains a syntax
error or constraint violation. For example consider the constraint:

6.7p4 All declarations in the same scope that refer to the same object or
function shall specify compatible types.
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"?
Nov 14 '05 #43


ba************@gmail.com wrote:
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).
Bahadir


Nov 14 '05 #44
On Mon, 13 Jun 2005 03:38:51 +0000, Peter "Shaggy" Haywood wrote:
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!
Lawrence Kirby wrote:

However these aren't the only requirements of a conforming implementation.
It must for example generate a diagnostic if the program contains a syntax
error or constraint violation. For example consider the constraint:

6.7p4 All declarations in the same scope that refer to the same object or
function shall specify compatible types.
You misunderstand overloaded functions.


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.
suppose:

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


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.
They are *not* the same object of course. They are TWO different
functions, that's the point!


But only in a language that is not C and violates the rules of the C
language. That's the point.
Lawrence
Nov 14 '05 #45

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by cybertof | last post: by
2 posts views Thread by desktop | last post: by
4 posts views Thread by king kikapu | last post: by
1 post views Thread by bob | last post: by
9 posts views Thread by Lawrence Krubner | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.