Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > does varargs offer a kind of poor man's polymorphism?

Reply
Thread Tools

does varargs offer a kind of poor man's polymorphism?

 
 
pete
Guest
Posts: n/a
 
      12-17-2010

No doubt every other student of C has noticed this; it's new to me.

If I declare:

int xlate( void *, ... );

and then define xlate( ) in several different ways (maybe all
definitions but one are #ifdef-ed out):

int xlate ( char *arg1 ) { ... }
int xlate ( int arg1, char *arg2, int arg3 ) { ... }
int xlate ( char arg1, int *arg2 ) { ... }

and omit any mention of va_list -- never mentioning it -- in every
definition of xlate( ); and then call xlate( ) abiding by one of its
several definitions, it seems that every compiled version of xlate( )
works just the way I want, at least under gcc and msvc.

Is this relaxed, undemanding, generous compiler behavior guaranteed
under C99?

Thanks!

-- Pete
 
Reply With Quote
 
 
 
 
Seebs
Guest
Posts: n/a
 
      12-17-2010
On 2010-12-17, pete <(E-Mail Removed)> wrote:
> Is this relaxed, undemanding, generous compiler behavior guaranteed
> under C99?


No, and there's been many counterexamples on real-world architectures.

Don't do that.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / http://www.velocityreviews.com/forums/(E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
 
Reply With Quote
 
 
 
 
pete
Guest
Posts: n/a
 
      12-17-2010
On Dec 16, 9:35*pm, Seebs <(E-Mail Removed)> wrote:
> On 2010-12-17, pete <(E-Mail Removed)> wrote:
>
> > Is this relaxed, undemanding, generous compiler behavior guaranteed
> > under C99?

>
> No, and there's been many counterexamples on real-world architectures.
>
> Don't do that.
>
> -s
> --
> Copyright 2010, all wrongs reversed. *Peter Seebach / (E-Mail Removed)://www.seebs.net/log/<-- lawsuits, religion, and funny pictureshttp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
> I am not speaking for my employer, although they do rent some of my opinions.


Peter, if it's convenient, would you please be good enough to point me
to just any random one of these many counterexamples?

Thanks so much!

-- p
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      12-17-2010
On 12/16/2010 8:58 PM, pete wrote:
>
> No doubt every other student of C has noticed this; it's new to me.
>
> If I declare:
>
> int xlate( void *, ... );
>
> and then define xlate( ) in several different ways (maybe all
> definitions but one are #ifdef-ed out):
>
> int xlate ( char *arg1 ) { ... }
> int xlate ( int arg1, char *arg2, int arg3 ) { ... }
> int xlate ( char arg1, int *arg2 ) { ... }


Each of the three would have to be in a separate compilation unit,
and at least two would have to be `static', and none of the three
compilation units could "see" the declaration. In other words,

1) In a single compilation unit, a name can be defined at most
once.

2) In a single program, a name with external linkage can refer
to only one function, hence one function definition.

3) In a single compilation unit, all declarations and definitions
of a function must agree.

> and omit any mention of va_list -- never mentioning it -- in every
> definition of xlate( ); and then call xlate( ) abiding by one of its
> several definitions, it seems that every compiled version of xlate( )
> works just the way I want, at least under gcc and msvc.


... whatever "works just the way I want" may mean.

> Is this relaxed, undemanding, generous compiler behavior guaranteed
> under C99?


You haven't described "works just the way I want," so the question
is not well-formed. Even so, I'll venture an answer: NO. I'll also
give the C90 answer: NO. And I'll make a guess at the C1x answer: NO.
What part of "NO" are you having trouble understanding? (And, out of
curiosity, why do you use "polymorphism" to describe what most people
term either "overloading" or "Haddocks' Eyes?")

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
luser- -droog
Guest
Posts: n/a
 
      12-17-2010
On Dec 16, 9:25*pm, Eric Sosman <(E-Mail Removed)> wrote:
>*(And, out of
> curiosity, why do you use "polymorphism" to describe what most people
> term either "overloading" or "Haddocks' Eyes?")


Yeah. You can't do polymorphism in C (or function dispatch based on
types) without some non-standard extension like gs's typeof,
or maybe with user-defined tag-unions.

BTW, what's "Haddocks' Eyes"? It sounds so tantalizingly mysterious!
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      12-17-2010
On 12/16/2010 10:49 PM, luser- -droog wrote:
> On Dec 16, 9:25 pm, Eric Sosman<(E-Mail Removed)> wrote:
>> (And, out of
>> curiosity, why do you use "polymorphism" to describe what most people
>> term either "overloading" or "Haddocks' Eyes?")

>
> Yeah. You can't do polymorphism in C (or function dispatch based on
> types) without some non-standard extension like gs's typeof,
> or maybe with user-defined tag-unions.


The former is non-standard, but the latter need not be.

> BTW, what's "Haddocks' Eyes"? It sounds so tantalizingly mysterious!


GIYF.

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      12-17-2010
On 12/16/2010 11:32 PM, Ered China Luin wrote:
> [...]
> You can pass any type through a var-args call, but get the arguments with va_arg
> and don't lie about the type.


Note that va_arg() must specify the *promoted* type: `double' and
`int' instead of `float' and `short', for example. This makes trouble
with types whose promotion rules differ from one system to another.
For example, in

enum TriplePlay { TINKER, EVERS, CHANCE } infielder = CHANCE;
void func(const char *, ...);
func ("What is the type of the second parameter?", infielder);

The type of the second *argument* is `enum TriplePlay', which we know
is "compatible with char, a signed integer type, or an unsigned integer
type," at the implementation's discretion. The compatible type the
implementation chooses may (or may not be) subject to promotion, and if
promotable may promote to pretty much anything. So, what type should
the va_arg() macro use to retrieve the second parameter? Different
implementations will give different answers (and `enum TriplePlay' will
not be among them, if that is a promotable type).

Even `size_t' and `ptrdiff_t' are theoretically subject to this
problem, although in practice they are usually wide enough that they
do not promote. Still, it is possible for a Standard-conforming C to
have `SIZE_MAX < INT_MAX', and if this happens a `size_t' argument
will promote to an `int' parameter and `va_arg(ap, size_t)' will be
incorrect.

For ultimate safety in passing (possibly) promotable types to
varargs functions, I guess you could wrap the suspect value in a
struct or union, types that are never promoted:

union Wrapper { enum TriplePlay payload; } carrier;
carrier.payload = infielder;
func ("The second parameter is a `union Wrapper'.", carrier);

Another possibility is to pass a pointer:

func ("The second parameter points to an `enum TriplePlay'.",
&infielder);

I confess, though, that I've never seen these dodges used -- not even
by people who've previously fallen afoul of an unexpected promotion!

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      12-17-2010
On 2010-12-17, pete <(E-Mail Removed)> wrote:
> Peter, if it's convenient, would you please be good enough to point me
> to just any random one of these many counterexamples?


Don't remember which systems, but there are systems where variadic
functions have all arguments passed on the stack, but other functions
typically use registers for at least some arguments, such as floating
point values.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      12-17-2010
Thanks, everyone. I appreciate all the comments and course
corrections.

-- pete
----------
"it means just what I choose it to mean -- neither more nor less"
-- Humpty Dumpty
 
Reply With Quote
 
David Thompson
Guest
Posts: n/a
 
      12-27-2010
On Fri, 17 Dec 2010 00:48:34 -0500, Eric Sosman
<(E-Mail Removed)> wrote:

> On 12/16/2010 11:32 PM, Ered China Luin wrote:
> > [...]
> > You can pass any type through a var-args call, but get the arguments with va_arg
> > and don't lie about the type.

>
> Note that va_arg() must specify the *promoted* type: `double' and
> `int' instead of `float' and `short', for example. This makes trouble
> with types whose promotion rules differ from one system to another.
> For example, [enum which may be (compatible with) any integer type]
> at the implementation's discretion. The compatible type the
> implementation chooses may (or may not be) subject to promotion, and if
> promotable may promote to pretty much anything. So, what type should


In principle, but enums in C can never exceed the range of 'int',
which is also normatively (though ill-definedly) 'the natural size'
for the execution environment, so I see no good reason ever to use
anything wider. An implementation can reasonably narrower integers,
but they are all taken to int by the default promotions. Have you seen
actual problems here?

> the va_arg() macro use to retrieve the second parameter? Different
> implementations will give different answers (and `enum TriplePlay' will
> not be among them, if that is a promotable type).
>
> Even `size_t' and `ptrdiff_t' are theoretically subject to this
> problem, although in practice they are usually wide enough that they
> do not promote. Still, it is possible for a Standard-conforming C to
> have `SIZE_MAX < INT_MAX', and if this happens a `size_t' argument
> will promote to an `int' parameter and `va_arg(ap, size_t)' will be
> incorrect.
>

Yeah, that one is usually okay but could be a problem.

Similarly but without vararg, getting socklen_t to port right has
wasted more of my time than can be justified in any sane universe.

<snip rest>
 
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
Poor, poor P&S owner learns too late... Rich Digital Photography 66 06-11-2009 04:48 AM
Special Offer....!!!! Obtian CCNA+CCNP Without Exams In 10 Days(100% Passing Gaurantee)...HURRY UP...!!!!....Limited Time Offer...!!!!!! mcsd_exams@yahoo.com Cisco 0 07-28-2006 11:29 AM
Poor reception, poor connection, and dropped signal =?Utf-8?B?dW51c3VhbHBzeWNobw==?= Wireless Networking 2 06-07-2006 12:54 AM
NZ has such poor broadband Microsoft is worried they cannot offer "Live" news.xtra.co.nz NZ Computing 29 12-03-2005 10:12 AM
Does no one else think microsoft does a poor job? =?Utf-8?B?SmVyZW15IEx1bmRncmVu?= Wireless Networking 2 11-20-2004 12:17 AM



Advertisments