views:

93

answers:

3

I am writing a library for C, and one function can return either a string (char *), an integer or a double. Next to that, the length of the string is unknown. I really don't know how to deal with this problem. I thought about using pointers as arguments to the function but that is really messy.

Can anyone give me a solution, and maybe some short sample code? Thanks.


Edit

What about a void pointer as return type, and a pointer to the size of the returned value as argument:

void* func(int x, int y, int *size) { ... }
/* or */
void* func(int x, int y, int &size) { ... }
/* always confused about them ): */

?

+6  A: 

It sounds like really bad design, but if you feel that you have to do this for some reason then you could use a union to return different types.

Paul R
+1 for bad design, or at least dangeresque.
Carl Norum
I like the union idea. Returning unions as function values is supported in modern C's, isn't it?
Carl Smotricz
Does a union really help? How does the caller know which union field to access?
bta
@bta: if you can't infer the return type from context (which would be a little weird, but we already know this is a bad design) then you could always embed the union in a struct with an enum field which signifies the valid type within the union.
Paul R
Paul R
A: 

You're going to have to redesign your function, or have multiple versions based on type.

Just think about it - how would the compiler be able to handle it? Assuming the implementation is in a separate .c file, the function is a black box to the compiler, so it has no idea what to expect.

You could either one version of the function for each type, or return a pointer, or take a pointer as an argument and store the value in there (which could be unsafe if the size of your result is unknown).

EboMike
+3  A: 

If a function can return multiple types, I would not recommend using a union (not alone, at least). Your function needs to return two pieces of information: the result, and the type of the result. You might get the best mileage out of using a structure like this one:

enum return_val_type {STRING, INT, DOUBLE};
struct return_val {
    enum return_val_type return_type;
    union {
        char*  s;
        int    i;
        double d;
    };
};

That way, the caller can check the value of return_type and determine how they need to interpret the data (that is, which union field to use).

bta