3

I have to do a function that takes in a variable of any data type and return a variable of the same data type. I have no idea how to do this all I know is that I have to use void as a data type of my parameters so all I have is this and obviously is doesn't work:

void better (void a, void b)
{
    if ( a > b )
        return a;
    else if ( b > a )
        return b;
}

So my question would be what is the right way to do this? This is not my exact assignment I just want to understand how it works.

Skaiste
  • 75
  • 5
  • 3
    Void is not a type... So macros or C++ templates... Choose your poison... – Macmade May 12 '14 at 18:22
  • 1
    It is not possible to implement "a function that takes in a variable of any data type and return a variable of the same data type" in C. Apparently, you either misunderstood something. Or maybe the statement of the problem calls for some rather wild interpretation. – AnT stands with Russia May 12 '14 at 18:23
  • 1
    @Macmade: `void` is a type. In C language `void` is an incomplete type that has no values (which cannot be completed). – AnT stands with Russia May 12 '14 at 18:25
  • 2
    "Void *" however is often used as a generic type. – Max May 12 '14 at 18:27
  • @Max: It is used as a generic *pointer* type. – AnT stands with Russia May 12 '14 at 18:27
  • Use C++ :-) [dummytext] – Peter - Reinstate Monica May 12 '14 at 18:28
  • 1
    `void` is a type. Specifically, it's an incomplete type that cannot be completed. It cannot be used as a parameter type. – Keith Thompson May 12 '14 at 18:31
  • 1
    "*This is not my exact assignment*" -- Well that's good because the problem as stated cannot be solved in C. There are ways to do something *similar* to what you describe using `void*`, not `void`, but without a precise and possible problem statement I don't think we can help. – Keith Thompson May 12 '14 at 18:32
  • See also http://stackoverflow.com/questions/2734808/variant-datatype-library-for-c and http://stackoverflow.com/questions/23118117/possible-to-check-return-type-of-a-function – nobody May 12 '14 at 20:28

3 Answers3

1

Perhaps it would help to first identify compare methods:

typedef enum CMPTYPE_E
   {
   CMPTYPE_STRCMP,
   CMPTYPE_INT
// ..etc
   } CMPTYPE_T;

Then, a method can be supplied to compare each defined type:

void *better (void *a, void *b, CMPTYPE_T cmpType)
   {
   switch(cmpType)
      {
      case CMPTYPE_STRCMP:
         return(strcmp(a,b) > 1 ? a : b);

      case CMPTYPE_INT:
         return((*((int *)a) > *((int *)b)) ? a : b);         

 //   ...etc
      }
   }        
Mahonri Moriancumer
  • 5,993
  • 2
  • 18
  • 28
  • I used this, but I get error: void value not ignored as it ought to be and a warning: warning: dereferencing ‘void *’ pointer. I've tried to write data types before each variable, for example: (int)*a > (int)*b. but then it shouts: invalid use of void expression. – Skaiste May 12 '14 at 19:21
  • @Skaiste, sorry; (my bad). In some cases you will have to cast values to the proper types in order to compare them. (Edited answer to show casting of 'void *' to 'int *' so that they can be compared as integer values. – Mahonri Moriancumer May 12 '14 at 19:41
1

What you're trying to do is create a sort of generalized function that takes arguments of some type and returns the larger value, in the same type.

Problem is, you actually can't do this in C. Although it's true that several C primitive types can be compared using the same kind of > logic, not all of them can be compared meaningfully like that, and even if they could, the compiler won't let you do this-- there's just no way to say "argument with unknown type" and "return whatever type the argument was".

C requires you to define the type explicitly, which usually means creating a different version of this function for every type you want to support. In other words, make a better_int function, and a better_float function, etc, and then call the appropriate one.


In this case, it's also possible to use other compiler features, called macros, to essentially autogenerate this comparison code for you right before compiling the code. This can achieve your goal, but doesn't do it with pure C constructs. Feel free to ask more about this approach if you still want to solve this problem this way.

Ben Zotto
  • 70,108
  • 23
  • 141
  • 204
0

If you are limited to C, you can use void* as your parameter types and return type as well. This works, but there is no protection from the compiler if you pass in the wrong type(s). You have to take care to manage the variables and make sure that if you pass in a char* for instance, that the function handles it as such and not as something else.

Also note that you are now dealing with pointers and addresses rather than primitive types. This introduces a new level of complication to your logic, especially if you allocate memory (e.g. malloc) for the return value that must be later freed.

edtheprogrammerguy
  • 5,957
  • 6
  • 28
  • 47