By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,592 Members | 1,958 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,592 IT Pros & Developers. It's quick & easy.

Union type variable assignation --- in expression, in function argues

P: n/a
Hi, C lovers!

I stuck on an union problem

Here is snippet of my code

....

/* two pointers of function with repsectively one and two argues */
typedef int (*dce_sn_f)(dce_t*);
typedef int (*dce_io_f)(dce_t*, FILE*);

/* A union to store one of the previous declared type */
typedef union {
dce_sn_f sn; /* func with dce_t* argue */
dce_io_f io; /* func with dce_t* and FILE argues */
} dce_f;

....

typedef struct dce_slot_st {
dce_f f; /* may be dce_dn_t or dce_io_t */
const char *name;
} dce_slot_t;

....

static dce_slot_t *build_slot( dce_f fun, const char *name )
{
dce_slot_t *new_slot;

new_slot = utl_calloc( sizeof(dce_slot_t) );
if (new_slot) {
new_slot->f = fun; /* XXXXXX */
new_slot->name = name;

} else {
UTL_SYSERR( "cannot create new slot" );
return NULL;
}

return new_slot;

}

.....

dc->init = build_slot( stub_init, "stub_init" );
gcc detect an error on this last line and said:
" incompatible type for argument 1 of `build_slot' "

Does somedy show what is bad in my code

Does the expression (marked wih XXXXX in the code), look correct ? gcc
does not complain about it !

Thanks a lot

Denis
Nov 14 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Denis Pithon wrote:
dc->init = build_slot( stub_init, "stub_init" );

gcc detect an error on this last line and said:
" incompatible type for argument 1 of `build_slot' "

Does somedy show what is bad in my code


stub_init is undeclared.

--
pete
Nov 14 '05 #2

P: n/a
pete wrote:
Denis Pithon wrote:

dc->init = build_slot( stub_init, "stub_init" );

gcc detect an error on this last line and said:
" incompatible type for argument 1 of `build_slot' "

Does somedy show what is bad in my code

stub_init is undeclared.


Badly, stub_init is well declared ( just forget to copy it in the mail)

I obtain the same error with the simpler code below

#include <stdio.h>
#include <stdlib.h>
typedef int (*f1_t)(int);
typedef int (*f2_t)(int, char*);
typedef union {
f1_t f1;
f2_t f2;
} f_t;
typedef struct {
f_t fun;
const char *name;
} f_slot_t;
int my_func(int a)
{
return a;
}
f_slot_t *do_work( f_t fun, const char *name )
{
f_slot_t *f = calloc( 1, sizeof(f_slot_t) );
f->fun = fun;
f->name = name;
return f;
}
int main()
{
f_slot_t *sl;
sl = do_work( my_func, "my_func" );
return 0;
}
Nov 14 '05 #3

P: n/a
Denis Pithon wrote:

pete wrote:
Denis Pithon wrote:
typedef union {
f1_t f1;
f2_t f2;
} f_t; int my_func(int a)
{
return a;
} f_slot_t *do_work( f_t fun, const char *name ) sl = do_work( my_func, "my_func" );

my_func isn't a union.
The first argument to do_work, should be a union.

--
pete
Nov 14 '05 #4

P: n/a
pete wrote:
Denis Pithon wrote:
pete wrote:
Denis Pithon wrote:

typedef union {
f1_t f1;
f2_t f2;
} f_t;


int my_func(int a)
{
return a;
}


f_slot_t *do_work( f_t fun, const char *name )


sl = do_work( my_func, "my_func" );


my_func isn't a union.
The first argument to do_work, should be a union.


I compile the code with
gcc -Wall -W -pedantic union.c

I just found that if remove -pedantic (eventually replace by -ansi), all
seems to be fine, if I cast my_func to (f_t) type, ie:

sl = do_work( (f_t) my_func, "my_func" );

compile quietly with: gcc -Wall -W -ansi union.c

If i keep -pedantic flag, gcc tell me that "ISO C forbids casts to union
type"...

So, I have to wrote as many do_work functions that I have type in the
union ???

Is there another way to it ?
Nov 14 '05 #5

P: n/a
"Denis Pithon" <de**********@boost-technoogies.com> wrote in message
news:40**********************@news.free.fr...
pete wrote:
Denis Pithon wrote:
pete wrote:

Denis Pithon wrote:

typedef union {
f1_t f1;
f2_t f2;
} f_t;


int my_func(int a)
{
return a;
}


f_slot_t *do_work( f_t fun, const char *name )


sl = do_work( my_func, "my_func" );


my_func isn't a union.
The first argument to do_work, should be a union.


I compile the code with
gcc -Wall -W -pedantic union.c

I just found that if remove -pedantic (eventually replace by -ansi), all
seems to be fine, if I cast my_func to (f_t) type, ie:

sl = do_work( (f_t) my_func, "my_func" );

compile quietly with: gcc -Wall -W -ansi union.c

If i keep -pedantic flag, gcc tell me that "ISO C forbids casts to union
type"...

So, I have to wrote as many do_work functions that I have type in the
union ???

Is there another way to it ?


The problem is that you are trying to pass
the ADDRESS OF A FUNCTION as parameter that
expects a union aggregate.

You should change the function parameter to
accept a pointer to the union, rather than
the union itself. Then allocate the union
somewhere and stuff the function pointer
into that union. Then pass the address of
the union to your do_work function.

Turn the warnings back on. They are telling
you that you screwed up big time. Put in the
suggested fixes and turn on the warnings.
--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS!
Are ISV upgrade fees too high? Check our custom product development!
Nov 14 '05 #6

P: n/a
Denis Pithon wrote:

pete wrote:
Denis Pithon wrote:

dc->init = build_slot( stub_init, "stub_init" );

gcc detect an error on this last line and said:
" incompatible type for argument 1 of `build_slot' "

Does somedy show what is bad in my code

stub_init is undeclared.


Badly, stub_init is well declared ( just forget to copy it in the mail)

I obtain the same error with the simpler code below

#include <stdio.h>
#include <stdlib.h>
typedef int (*f1_t)(int);
typedef int (*f2_t)(int, char*);
typedef union {
f1_t f1;
f2_t f2;
} f_t;
typedef struct {
f_t fun;
const char *name;
} f_slot_t;
int my_func(int a)
{
return a;
}
f_slot_t *do_work( f_t fun, const char *name )
{
f_slot_t *f = calloc( 1, sizeof(f_slot_t) );
f->fun = fun;
f->name = name;
return f;
}
int main()
{
f_slot_t *sl;
sl = do_work( my_func, "my_func" );
return 0;
}

I couldn't help but notice, that unions don't
seem to have anything to do with your posted code.
Your function doesn't make any use of a union type parameter,
and you don't have any unions available outside the function,
to pass as arguments. "fun" and "name", are structure members.

--
pete
Nov 14 '05 #7

P: n/a
Denis Pithon wrote:
pete wrote:
Denis Pithon wrote:
pete wrote:

Denis Pithon wrote:



typedef union {
f1_t f1;
f2_t f2;
} f_t;


int my_func(int a)
{
return a;
}


f_slot_t *do_work( f_t fun, const char *name )


sl = do_work( my_func, "my_func" );


You must use something like:

sl = do_work(cast_from_f1_to_f (my_func), "my_func" );

where:

f_t cast_from_f1_to_f (f1_t f1)
{
f_t f;

return f.f1 = f1;
}

Another question is how you detect wich member of the union contain
correct data. In unions only one member contain correct data (there are
some exeptions, see standart), so you must store some additional info
about what member to use.

In your case you can use void * type instead of union.

typedef void *f_t

/* ... */

sl = do_work ((void *)my_func, "my_func");

Cast is needed there because standart doesn't allow explicit cast to
pointers to functions.

Nov 14 '05 #8

P: n/a
Victor Nazarov wrote:

Denis Pithon wrote:
> pete wrote:
>
>> Denis Pithon wrote:
>>
>>> pete wrote:
>>>
>>>> Denis Pithon wrote:
>>
>>
>>
>>
>>
>>> typedef union {
>>> f1_t f1;
>>> f2_t f2;
>>> } f_t;
>>
>>
>>
>>
>>> int my_func(int a)
>>> {
>>> return a;
>>> }
>>
>>
>>
>>
>>> f_slot_t *do_work( f_t fun, const char *name )
>>
>>
>>
>>
>>> sl = do_work( my_func, "my_func" );


You must use something like:

sl = do_work(cast_from_f1_to_f (my_func), "my_func" );

where:

f_t cast_from_f1_to_f (f1_t f1)
{
f_t f;

return f.f1 = f1;
}

Another question is how you detect wich member of the union contain
correct data. In unions only one member contain correct data (there are
some exeptions, see standart), so you must store some additional info
about what member to use.

In your case you can use void * type instead of union.

typedef void *f_t

/* ... */

sl = do_work ((void *)my_func, "my_func");

Cast is needed there because standart doesn't allow explicit cast to
pointers to functions.


I don't understand what you're saying.
You can't cast a function pointer to (void *),
therfore cast is not allowed there.

--
pete
Nov 14 '05 #9

P: n/a
pete wrote:
Victor Nazarov wrote:
I don't understand what you're saying.
You can't cast a function pointer to (void *),
therfore cast is not allowed there.


I've ment you need cast-operator in expression
p = (void *)my_func
where p was defined as void *;
I really don't know what standart says about this assignment, but that
has worked on my implementation so I could lately cast p back to pinter
to function. So I've just spread the idea of ALMOSTANYTYPE *
representation as void * to pointers to functions.
I want to know if that was a misstake. So I'm sorry if it was.
Sorry for my english.

Vir

Nov 14 '05 #10

P: n/a
Victor Nazarov wrote:

pete wrote:
Victor Nazarov wrote:
I don't understand what you're saying.
You can't cast a function pointer to (void *),
therfore cast is not allowed there.


I've ment you need cast-operator in expression
p = (void *)my_func
where p was defined as void *;
I really don't know what standart says about this assignment, but that
has worked on my implementation so I could lately cast p back to pinter
to function. So I've just spread the idea of ALMOSTANYTYPE *
representation as void * to pointers to functions.
I want to know if that was a misstake.


Yes, it is a mistake. It is a nonstandard extension.
Pointers to functions,
can be converted to pointers to other types of functions,
but (void *), is a pointer to an incomplete object type,
and is incompatible with function pointers.

--
pete
Nov 14 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.