473,398 Members | 2,188 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

unions as function args

AFAIK there is no way in C to define one single function argument so
that two ore more explicitly declared types are allowed to pass
(so, either you pass the exact type or you need casts which I explicitly
do *not* want to consider here).

With the touch of a C enhancement in mind, I wonder, though, why
this shouldn't be allowed (it is *not* at least by my C compiler
gcc):

union u{
int i;
long l;
char* pc;
};

void f(u arg){
/* ... */
}

void main(int argc,char** argv){
i=99;
f(i); /* <-- INCOMPATIBLE TYPE */
}

Yes, of course, i is an int while union u is needed. On the other hand:
Wouldn't type checking be possible since all allowed types are defined
by the union u?

Thank You
Felix
May 13 '07 #1
8 1298
void main(int argc,char** argv){
i=99;
f(i); /* <-- INCOMPATIBLE TYPE */
}
Typo: "i=99;" should be "int i=99;"

Felix
May 13 '07 #2
"Felix Kater" <fk****@googlemail.comschrieb im Newsbeitrag
news:20****************************@googlemail.com ...
AFAIK there is no way in C to define one single function argument so
that two ore more explicitly declared types are allowed to pass
(so, either you pass the exact type or you need casts which I explicitly
do *not* want to consider here).

With the touch of a C enhancement in mind, I wonder, though, why
this shouldn't be allowed (it is *not* at least by my C compiler
gcc):

union u{
int i;
long l;
char* pc;
};

void f(u arg){
void f(union u u) {
/* ... */
}

void main(int argc,char** argv){
int main (void) { /* int as that's the only standard conforming way, (void)
because you apparently don't use argc or argv */
i=99;
union u u;
u.i=99;
f(i); /* <-- INCOMPATIBLE TYPE */
f(u);
return 0;
}

Yes, of course, i is an int while union u is needed. On the other hand:
Wouldn't type checking be possible since all allowed types are defined
by the union u?

Thank You
Felix
Bye, Jojo
May 13 '07 #3
Felix Kater wrote:
AFAIK there is no way in C to define one single function argument so
that two ore more explicitly declared types are allowed to pass
(so, either you pass the exact type or you need casts which I explicitly
do *not* want to consider here).

With the touch of a C enhancement in mind, I wonder, though, why
this shouldn't be allowed (it is *not* at least by my C compiler
gcc):

union u{
int i;
long l;
char* pc;
};

void f(u arg){
/* ... */
}

void main(int argc,char** argv){
main() should return int. Even if you don't actually return anything.
i=99;
f(i); /* <-- INCOMPATIBLE TYPE */
}

Yes, of course, i is an int while union u is needed. On the other hand:
Wouldn't type checking be possible since all allowed types are defined
by the union u?
It would have been possible for C to be defined in a way that allowed
this, but it isn't so. You can use f((union u) { .i = i }); (this
isn't a cast), but it looks hideous.

However, even if you manage to call f like that, how is it going to
know what type of argument you passed?

May 13 '07 #4
On 13 May 2007 05:33:05 -0700
Harald van Dijk <tr*****@gmail.comwrote:
It would have been possible for C to be defined in a way that allowed
this, but it isn't so. You can use f((union u) { .i = i }); (this
isn't a cast), but it looks hideous.
Interesting.
However, even if you manage to call f like that, how is it going to
know what type of argument you passed?
That, of course, would be up to further implementation by the user.

For simple types I imagine that (like the need of passing an
arg_count or similar to variable argument lists) you need to pass the
type information. (This is *not* the same as if we'd just created two
functions since it helps abstracting like arg_count does.) Complex types
(structs) could carry its type information as the first value in
the struct which is a common tecnique.

Felix
May 13 '07 #5
Rg
On May 13, 9:05 am, Felix Kater <fka...@googlemail.comwrote:
>
[...]
union u{
int i;
long l;
char* pc;
};

void f(u arg){
[...]
f() parameters are also wrong. The C-style of declaring struct or
union data requires the struct or union word:

void f(union u arg) {
/* ... */

----
rg

May 13 '07 #6
Felix Kater <fk****@googlemail.comwrote:
>With the touch of a C enhancement in mind, I wonder, though, why
this shouldn't be allowed (it is *not* at least by my C compiler
gcc):
I can't think of why it would be impossible to implement this feature in
a compiler.

This is vaguely related:

I was messing with the Unix semctl() call last night:

int semctl(int semid, int semnum, int cmd, ...);

The 4th parameter is a user-defined union semun which looks like this:

union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};

In that case, could I call semctl() like this?

int i = 1;

semctl(semid, 0, SETVAL, i);

I think I could, but only with the scary assumption that semctl()
doesn't attempt to access i as one of the other union members, where
that other member was larger in size than i.

-Beej

May 13 '07 #7
Felix Kater <fk****@googlemail.comwrites:
AFAIK there is no way in C to define one single function argument so
that two ore more explicitly declared types are allowed to pass
(so, either you pass the exact type or you need casts which I explicitly
do *not* want to consider here).

With the touch of a C enhancement in mind, I wonder, though, why
this shouldn't be allowed (it is *not* at least by my C compiler
gcc):

union u{
int i;
long l;
char* pc;
};

void f(u arg){
"u arg" needs to be "union u arg".
/* ... */
}

void main(int argc,char** argv){
main returns int, not void.
i=99;
int i = 99; (as you mentioned in a followup)
f(i); /* <-- INCOMPATIBLE TYPE */
}

Yes, of course, i is an int while union u is needed. On the other hand:
Wouldn't type checking be possible since all allowed types are defined
by the union u?
This isn't allowed because the argument i is of type int, and the
parameter arg is of type union u. They're two distinct types, and
there's no implicit conversion between them. A "union u" isn't an
int, it merely contains an int.

Now it would have been easy enough for the language to support this,
by defining an implicit conversion between a union type and any of its
member types.

But the language already has plenty of mechanisms for doing this kind
of thing. Unions are tricky enough as it is; accessing any member
other than the one most recently stored invokes undefined behavior
(though I think there are exceptions for things like character types,
and for types whose representation is guaranteed to be the same).

The function needs to know *which* member of the union is current. A
good way to do that is to wrap the union in a structure, which has
another member that tells you which union member is active:

struct variant {
enum { i_is_active, l_is_active, pc_is_active } discriminant;
union {
int i;
long l;
char *pc;
} u;
};

Constructing a value of this type is a little tricky, especially in
C90.

Or you can use a variadic function, using the <stdarg.hheader, with
a single fixed argument specifying the type of the second argument.
This is how printf() works.

There are almost infinitely many features that C *could* support, and
almost every one of them could be useful in some context. But if they
were all added, the standard document would collapse into a
gravitational singularity. The obvious solution is to add just the
features that *I* think would be useful, but nobody else would like
the result.

--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
May 13 '07 #8
On 13 May 2007 05:33:05 -0700, Harald van D?k <tr*****@gmail.com>
wrote:
Felix Kater wrote:
AFAIK there is no way in C to define one single function argument so
that two ore more explicitly declared types are allowed to pass
(so, either you pass the exact type or you need casts which I explicitly
do *not* want to consider here).

With the touch of a C enhancement in mind, I wonder, though, why
this shouldn't be allowed (it is *not* at least by my C compiler
gcc):
<snip: pass to a union type>
It would have been possible for C to be defined in a way that allowed
this, but it isn't so. You can use f((union u) { .i = i }); (this
isn't a cast), but it looks hideous.
gcc _does_ allow _as an extension_ casting to a union, without using
the full (C99 standard) compound-literal syntax:
f ( (union u) i )

De gustibus whether this looks hideous or not.
However, even if you manage to call f like that, how is it going to
know what type of argument you passed?
Might be (an)other argument(s), or previous state, or shared/global
state, or any number of things. It is often better design to carry the
discriminant with the variant data, but not always.

- formerly david.thompson1 || achar(64) || worldnet.att.net
Jul 1 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Neil Zanella | last post by:
Hello, I would like to know whether the following C fragment is legal in standard C and behaves as intended under conforming implementations... union foo { char c; double d; };
16
by: Tim Cambrant | last post by:
Hi. I was reading up a bit on the features of C I seldom use, and I came across unions. I understand the concept, and that all the contained variables etc. share the same memory. Thus, when a new...
23
by: rohit | last post by:
Hi, In my couple of years of experience, I have never found a single instance where I needed to use unions and bitfields(though I have used structures).I was just imagining where would these find...
67
by: bluejack | last post by:
A recent post asking for help with unions reminded me of this component of the C language that I have only used a couple of times, and those almost entirely out of personal whim -- Unions for the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.