O
O
OccamaRazor2018-04-13 21:16:19
C++ / C#
OccamaRazor, 2018-04-13 21:16:19

Can't convert double to void*?

Implementation in pure "C"
I'm trying to make a function that takes data of any type and prints it (so far only int, char*, double), a problem with double : it gives an error about the impossibility of converting 13.3 to a pointer type. What is the correct way to pass a value to a macro and then to a function to store the value? While the only idea is to convert to string and then back to double, what would be the smartest and best approach?

#include <stdio.h>
#include <stdlib.h>

#define puts(x) _Generic((x),                     \
  char*:       _puts((void*) x, "str"),           \
  int:         _puts((void*) x, "int"),           \
  double:      _puts(*(void**)x, "float")          \
)


void _puts(void* d, const char* type)
{
  if (type == "int"){
    printf("%d", d);
  } else if (type == "float"){
    printf("%lf", d);
  } else {
    puts(d);
  }
}


int main(void) {
  convert("String");
  convert(1230);
  convert(13.3);

  return 0;
}

Answer the question

In order to leave comments, you need to log in

3 answer(s)
D
devalone, 2018-04-13
@devalone

template <typename T>
void print(const T& obj) {
    std::cout << obj;
}

M
MiiNiPaa, 2018-04-13
@MiiNiPaa

What don't you like about puts? By the way, you can't compare string literals like you do. "float" == "float" may well equal false. And since you have C++ tags: why a macro and not a template with static if, tag dispatch or just overloaded functions? printf("%s", d)

R
res2001, 2018-04-14
@res2001

Where is the convert() function?
You have already been answered about comparing strings.
But you still have complete garbage in printf. You pass void* to it, while in the template you have int and double. You need to do the conversion and dereferencing:

if (type == "int"){
    printf("%d", *((int*)d));
  } else if (type == "float"){
    printf("%lf", *((double*)d));

Well, instead of the strings "int, "float", ... it is better to use some integer constants - they can be compared directly.
In C, your idea is as beautiful as it is not possible to implement it in pros. Each data type needs its own function convert with a unique name (converti(int), convertd(double), ...).
There is no way for a macro to automatically know what type of data was passed to it, so your code will not compile.
You must explicitly specify which function to call to output (or explicitly specify which type data is transferred to it.)
For example, we have a set of functions for displaying the corresponding data type:
void putsi(int);
void putsd(double);
void putss(const char *);

#define PUTS(t, val)   puts ## t(val)

int main()
{
   PUTS(i, 123);
   PUTS(d, 3.14);
   PUTS(s, "hello world!");
  return 0;
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question