Reputation: 658
I'm quite new to C development and I would like to know if there's any way to return any type in a C function as this java code would:
public static Object returnAnyType(Object anyType){
//example useless code
return anyType;
}
public static void main(String[] args) {
System.out.println(returnAnyType('c'));
// outs 'c'
}
I know there's a way to return any type of pointers as void
pointers in C :
void* returnAny(void* anyType){
//example useless code
return anyType;
}
void main(){
char ch = 'c';
printf("%c\n", *(char*)returnAny(&ch));
// outs 'c'
}
and I would like to know if it's possible to have the same above java code in C without having to use void pointers either in return types and in parameters.
So far I've tried using void
for return types but my compiler doesn't accept return statement without return type.
Upvotes: 1
Views: 576
Reputation: 23218
Yes. There is a way to return [one of a selection of] type[s] in C functions without using void pointers. A struct that is defined to contain two members,
Because C is not an object oriented language such as Java
or Python
, the methods used to accomplish what you want in C
are not as elegant as what you might in the other laguages, but I have used this method in C, and gets the job done:
typedef enum {
CHAR,
INT,
DOUBLE,
UCHAR,
UINT,
... //etc etc etc
} TYPE;
typedef union {
char char_var;
int int_var;
double dble_var;
unsigned char uchar_var;
unsigned int uint_var;
... /// etc etc
}VAR;
typedef struct {
VAR var; // one of the types contained in union
TYPE type; // corresponding emum value indicating type sent
} DATA;
DATA data *pData;
This prototype can be used to pass any type (defined in the struct and union above):
DATA * returnAnyType(DATA *data);
Once the function processes its input and returns, the values returned can be fed into a printf
statement via a switch
statement. A very bare bones example illustrates:
int main(void)
{
DATA dataout = {12, INT};
DATA *datain = returnAnyType(&dataout);
if(datain)
{
switch( datain->type) {
case (CHAR):
printf("Type returned is \"char\", its value is: %c", datain->var.char_var);
break;
case (INT):
printf("Type returned is \"int\", its value is: %d", datain->var.int_var);
break;
// and so on
}
free(datain); memory created in called function, free here.
}
return 0;
}
DATA * returnAnyType(const DATA *data)
{
///////////////////////////////////////////////////////////////////////
// Do what ever manipulation is needed with "data" in this section,
// then package into pD for the return trip
/////////////////////////////////////////////////////////////////////
DATA *pD = calloc(1, sizeof *pD);//create pointer instance for return
//!! must be free in caller !!
if(pD)
{
pD->type = data->type;
switch (pD->type) {
case CHAR:
pD->var.char_var = data->var.char_var;
break;
case INT:
pD->var.int_var = data->var.int_var;
break;
// and so on ...
}
}
return pD;//free in caller function
}
Upvotes: 5
Reputation: 9062
In C is very hard to express relationships between objects. An object is simply a specific memory layout, and thus there is no way of casting between them. You can define conversion functions, but that's pretty much it.
Since there is no concept of relation between objects, there also is no object such as Java's Object
.
Therefore, not only is impossible to have a function that can return something more general, but is impossible to define a function that can return multiple types.
void*
works only because any pointer can be converted to void*
, not that is special in any sense.
Upvotes: 5