Can you printf value from a void * in C - c

Ok, I'm trying to do this, but it isn't working becuase I'm not dereferencing the pointer... is there a way to do it without making a switch statement for the type?
typedef struct
{
char *ascii_fmtstr;
int len;
int (*deserializer)(void *in, const char *ascii);
int (*serializer)(const void *in, char *ascii);
} FORMAT;
const FORMAT formats[]=
{
{"%d\n", 2/2} //Int
,{"%s\n", STRSIZE/2} //String
,{"%.4f\n", 4/2} //Float
,{"%lld", 4/2} //Long-Long
,{"%s\n", STRSIZE/2} //Time
};
typedef struct {
int fmtindex;
void * vp;
} JUNK;
float f = 5.0f;
int i=1;
char foo[]="bar";
JUNK j[] = {
{2, &f}
,{0, &i}
,{1, foo}};
void dump(void)
{
int i;
for(i=0;i<2;i++)
printf(formats[j[i].fmtindex].ascii_fmtstr, j[i].vp);
}

It seems like you're using void * as a cheap union. That's a pretty bad idea. I think you'll find unions in conjunction with enums and switches make this look so much neater, in C. You'll find the switch amongst the #ifdef SWITCH ... #else, and the switchless version amongst the #else ... #endif.
#include <stdio.h>
struct object {
enum type {
d=0,
s=1,
f=2,
lld=3,
time=4
} type;
union instance {
int d;
char *s;
float f;
long long lld;
char *time;
} instance;
};
#ifdef SWITCH
void print_object(struct object *o) {
switch (o->type) {
case d: printf("%d", o->instance.d); break;
case s: printf("%s", o->instance.s); break;
case f: printf("%f", o->instance.f); break;
case lld: printf("%lld", o->instance.lld); break;
case time: printf("%s", o->instance.time); break;
};
}
#else
void print_d(struct object *o);
void print_s(struct object *o);
void print_f(struct object *o);
void print_lld(struct object *o);
void print_time(struct object *o);
void print_object(struct object *o) {
void (*print_functions[])(struct object *) = {
[d] = print_d,
[s] = print_s,
[f] = print_f,
[lld] = print_lld,
[time] = print_time
};
print_functions[o->type](o);
}
void print_d(struct object *o) { printf("%d", o->instance.d); }
void print_s(struct object *o) { printf("%s", o->instance.s); }
void print_f(struct object *o) { printf("%f", o->instance.f); }
void print_lld(struct object *o) { printf("%lld", o->instance.lld); }
void print_time(struct object *o) { printf("%s", o->instance.time); }
#endif
int main(void) {
struct object o = { .type = d, /* type: int */
.instance = { .d = 42 } /* value: 42 */ };
print_object(&o);
return 0;
}

You can print the pointer itself with something like %p but, if you want to print what it points to, you need to tell it what it is:
printf ("%d", *((int*)myVoidPtr));
You're not allowed to dereference a void * simply because the compiler doesn't know what it points to.

Think about it this way : Any pointer simply points to a single memory location.But the type of the pointer determines how many bytes after that to interpret/consider.If it is char* then (depending on system) 1 byte is interpreted,if it is an int* 4 bytes are interpreted, and so on.But a void* had no type.So you can't dereference a void pointer in C due to this simple reason.But you can print out the address it points to using the %p format specifier in printf() and passing that void pointer as argument.
printf("The address pointed by void pointer is %p",void_ptr); //Correct
printf("The address pointed by void pointer is %p",(void*)int_ptr);//Correct
assuming int_ptr is an integer pointer,say,and void_ptr is a void pointer.
printf("Value at address pointed by void pointer is %d",*void_ptr);// Wrong
printf("Value at address pointed by void pointer is %d",*(void*)int_ptr);//Wrong

It is not clear what your real goal is. Yes, there are ways to print data type dependent. Basically the idea is to create your own print function.
But only supplying the pointer will not be enough. In any case you need to supply pointer and the type of it.
Lets assume we have a function myprint:
myprint("%m %m %m %i", TYPE_INT, &i, TYPE_FLOAT, &f, TYPE_STRING, foo, 10);
would be a possible call. myprint is a varargs function then which needs to reconstruct the format string and arguments and then can call real printf.
If you use heap variables only, the type of the variable can be stored together with the data with some tricks (hint: check how malloc stores the block size). This would make the additional arguments superflous.
There are other solutions to that, but a good suggestion is not possible without knowledge of your real goal and the exact conditions.

I think the printf and its friends (fprintf, etc.) can dereference only char* which will be interpreted as a c-string.
Actually you can write such function yourself, because you will tell your function how to dereference void* with format flags.
Also you can add to the formats as a third value a pointer to required dereference function that will take as argument a void* and will return the value instead of pointer.
So you will need to write a function for each of the types you use in your formats and assign each function to each format properly.

Related

Which type to use for an arbitrary function pointer in C?

In short, my question is: does the C standard allow for an arbitrary function pointer type similar to void * being an arbitrary data pointer type?
It is common to define call-back function types with a void * parameter to pass on an arbitrary data package whose format is known to the call-back function, but not to the caller.
For example:
typedef void (* EventFunctionType)(void *data);
void RegisterEventFunction(EventFunctionType function, void *data);
An "EventFunction" can then be registered with a data pointer which will be passed to the function when it is called.
Now suppose we want to pass a function pointer to the call-back. The function could have any prototype which would be known to the specific call-back function, just like the arbitrary data structure above.
A void * cannot hold a function pointer, so which type could be used?
Note: An obvious solution to this problem would be to wrap the function pointer in a data structure with the correct function pointer type, but the question is if the function pointer could be passed on directly in a generic form which the call-back could then cast to a pointer with the correct prototype?
There are no function pointer type that works the same as/similar to to void-pointer.
But function pointers has another characteristic that can be used. It's already referenced in the answer linked in this question:
In the C11 draft standard N1570, 6.3.2.3 ยง8:
A pointer to a function of one type may be converted to a pointer to a function of another type and back again.
This mean that you can use any function pointer type as your "arbitrary function pointer type". It doesn't matter as long as you know how to get back to the real/original type (i.e. know the original type so that you can cast correctly).
For instance:
typedef void (*func_ptr_void)(void);
and then use func_ptr_void as your "arbitrary function pointer type".
But notice that unlike conversion between void* and other object pointer types, the conversion between function pointers will always require an explicit cast. The code example below shows this difference:
#include <stdio.h>
typedef void (*func_ptr_void)(void);
typedef int (*f_int)(int);
int bar(int n)
{
return n * n;
}
int test(func_ptr_void f, int y)
{
f_int fc = (f_int)f; // Explicit cast
return fc(y);
}
int foo(void* p)
{
int* pi = p; // Explicit cast not needed
return *pi;
}
int main(void)
{
int x = 42;
void* pv = &x; // Explicit cast not needed
printf("%d \n", foo(pv));
func_ptr_void fpv = (func_ptr_void)bar; // Explicit cast
printf("%d \n", test(fpv, 5));
return 0;
}
does the C standard allow for an arbitrary function pointer type similar to void * being an arbitrary data pointer type?
No. Two function pointers are only compatible if their return types and parameters (including qualifiers) match.
However, pointer conversions between any two function pointers by means of a cast are well-defined (6.3.2.3/8) as long as you don't invoke the function through the wrong pointer type. This means that you can use any function pointer type as a "generic function pointer" as long as you keep track of what function that pointer actually points at. Such as using an extra enum for that purpose.
Generally when using function pointers, we don't do that however, but instead define a common interface. For example like the callbacks to bsearch/qsort which use the form int (*)(const void*, const void*).
Here's an example of "keep track of type using enum", which is not something I particularly recommend but otherwise perfectly well-defined:
#include <stdio.h>
static int intfunc (int x)
{
printf("%d\n", x);
return x;
}
static double doublefunc (double x)
{
printf("%f\n", x);
return x;
}
typedef enum
{
INTFUNC,
DOUBLEFUNC
} functype_t;
typedef void generic_func_t (void);
typedef int int_func_t (int);
typedef int double_func_t (double);
typedef struct
{
generic_func_t* fptr;
functype_t type;
} func_t;
void func_call (const func_t* f)
{
switch(f->type)
{
case INTFUNC: ((int_func_t*)f->fptr ) (1); break;
case DOUBLEFUNC: ((double_func_t*)f->fptr) (1.0); break;
}
}
int main (void)
{
func_t f1 = { (generic_func_t*)intfunc, INTFUNC };
func_t f2 = { (generic_func_t*)doublefunc, DOUBLEFUNC };
func_call(&f1);
func_call(&f2);
}
That's "old school" C, but it is not recommended since it is clunky, brittle and not really type safe. In modern C programming we wouldn't write that kind of code however, but replace that whole mess with something like this:
#include <stdio.h>
static int intfunc (int x)
{
printf("%d\n", x);
return x;
}
static double doublefunc (double x)
{
printf("%f\n", x);
return x;
}
#define func_call(obj) \
_Generic((obj), \
int: intfunc, \
double: doublefunc) (obj) \
int main (void)
{
func_call(1);
func_call(1.0);
}

Function Returning Itself

Is it possible to declare some function type func_t which returns that type, func_t?
In other words, is it possible for a function to return itself?
// func_t is declared as some sort of function pointer
func_t foo(void *arg)
{
return &foo;
}
Or would I have to use void * and typecasting?
No, you cannot declare recursive function types in C. Except inside a structure (or an union), it's not possible to declare a recursive type in C.
Now for the void * solution, void * is only guaranteed to hold pointers to objects and not pointers to functions. Being able to convert function pointers and void * is available only as an extension.
A possible solution with structs:
struct func_wrap
{
struct func_wrap (*func)(void);
};
struct func_wrap func_test(void)
{
struct func_wrap self;
self.func = func_test;
return self;
}
Compiling with gcc -Wall gave no warnings, but I'm not sure if this is 100% portable.
You can't cast function pointers to void* (they can be different sizes), but that's not a problem since we can cast to another function pointer type and cast it back to get the original value.
typedef void (*fun2)();
typedef fun2 (*fun1)();
fun2 rec_fun()
{
puts("Called a function");
return (fun2)rec_fun;
}
// later in code...
fun1 fp = (fun1)((fun1)rec_fun())();
fp();
Output:
Called a function
Called a function
Called a function
In other words, is it possible for a function to return itself?
It depends on what you mean by "itself"; if you mean a pointer to itself then the answer is yes! While it is not possible for a function to return its type a function can return a pointer to itself and this pointer can then be converted to the appropriate type before calling.
The details are explained in the question comp.lang.c faq: Function that can return a pointer to a function of the same type.
Check my answer for details.
Assume the function definition
T f(void)
{
return &f;
}
f() returns a value of type T, but the type of the expression &f is "pointer to function returning T". It doesn't matter what T is, the expression &f will always be of a different, incompatible type T (*)(void). Even if T is a pointer-to-function type such as Q (*)(void), the expression &f will wind up being "pointer-to-function-returning-pointer-to-function", or Q (*(*)(void))(void).
If T is an integral type that's large enough to hold a function pointer value and conversion from T (*)(void) to T and back to T (*)(void) is meaningful on your platform, you might be able to get away with something like
T f(void)
{
return (T) &f;
}
but I can think of at least a couple of situations where that won't work at all. And honestly, its utility would be extremely limited compared to using something like a lookup table.
C just wasn't designed to treat functions like any other data item, and pointers to functions aren't interchangeable with pointers to object types.
what about something like this:
typedef void* (*takesDoubleReturnsVoidPtr)(double);
void* functionB(double d)
{
printf("here is a function %f",d);
return NULL;
}
takesDoubleReturnsVoidPtr functionA()
{
return functionB;
}
int main(int argc, const char * argv[])
{
takesDoubleReturnsVoidPtr func = functionA();
func(56.7);
return 0;
}
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef void *(*fptr)(int *);
void *start (int *);
void *stop (int *);
void *start (int *a) {
printf("%s\n", __func__);
return stop(a);
}
void *stop (int *a) {
printf("%s\n", __func__);
return start(a);
}
int main (void) {
int a = 10;
fptr f = start;
f(&a);
return 0;
}
It is not possible for a function to return itself by value. However it is possible itself to return by a pointer.
C allows to define function types that take undefined number of parameters and those those types are compatible with function types that take defined parameters.
For example:
typedef void fun_t();
void foo(int);
fun_t *fun = foo; // types are fine
Therefore the following function would work.
void fun(void (**ptr)()) {
*ptr = &fun;
}
And below you can find the exemplary usage:
#include <stdio.h>
void fun(void (**ptr)()) {
puts("fun() called");
*ptr = &fun;
}
int main() {
void (*fp)();
fun(&fp); /* call fun directly */
fp(&fp); /* call fun indirectly */
return 0;
}
The code compiles in pedantic mode with no warnings for C89 standard.
It produces the expected output:
fun() called
fun() called
There's a way, you just try this:
typedef void *(*FuncPtr)();
void *f() { return f; }
int main() {
FuncPtr f1 = f();
FuncPtr f2 = f1();
FuncPtr f3 = f2();
return 0;
}
If you were using C++, you could create a State object type (presuming the state machine example usage) wherein you declare an operator() that returns a State object type by reference or pointer. You can then define each state as a derived class of State that returns each appropriate other derived types from its implementation of operator().

Using void * in C in place of overloading?

My question here is I had seen code like this for a multithreading application:
void Thread( void* pParams )
{
int *milliseconds = (int *)pParams;
Sleep(milliseconds);
printf("Finished after %d milliseconds", milliseconds); //or something like that
}
This greatly took my interest, I knew malloc sends back a void pointer and you can cast it to what you want, does this mean that I can create a function that can accept any data type?
For example a function I wrote without testing:
void myfunc( void* param )
{
switch(sizeof(param)) {
case 1:
char *foo = (char *)param; break;
case 2:
short *foo = (short *)param; break;
case 4:
int *foo = (int *)param; break;
}
}
myfunc(3.1415);
myfunc(0);
myfunc('a');
I may be completely wrong, even if this does work is it horrible practise? Thanks.
yes, void * is great for the creation of generic functions. However, once you pass a pointer to a certain datatype to a function that takes a void * you lose all type information. One way to steer your program so it knows which type you passed in is to have a 2nd parameter of type enum which may have values such as INT, FLOAT, DOUBLE etc. etc.
#include <stdio.h>
typedef enum inputTypes
{
INT,
DOUBLE,
CHAR
} inType;
void myfunc(void*, inType);
int main(void)
{
int i = 42;
double d = 3.14;
char c = 'a';
myfunc(&i, INT);
myfunc(&d, DOUBLE);
myfunc(&c, CHAR);
return 0;
}
void myfunc(void* param, inType type)
{
switch(type) {
case INT:
printf("you passed in int %d\n", *((int *)param));
break;
case DOUBLE:
printf("you passed in double %lf\n", *((double *)param));
break;
case CHAR:
printf("you passed in char %c\n", *((char *)param));
break;
}
}
Output
you passed in int 42
you passed in double 3.140000
you passed in char a
Yes, it is possible to create a function that accepts multiple type, but that is not how you do it.
In your myfunc, sizeof(param) will always be the same: sizeof is determined at compile time, and will be the size of a pointer.
The reason it works for threads, it generally it is known by the coder what the pointer points to, at compile time, and all you need is a simple cast. If you don't know at compile time what the void * points to, you must pass it at runtime somehow.
The key with void *: You can only cast them back to whatever they were in the first place, and it is up to you to know what that is. A simple void * by itself cannot tell you what it is pointing to.
sizeof(param) will always return the size of a pointer, so presumably 8 if you are on a 64-bit system. This has nothing to do with what it's pointing to.
Doesn't work because sizeof(param) is trying to take the size of a pointer.
The size of a void* is completely dependent on the system and determined at compile time, not on what is actually contained within it.

How to pass an array of struct using pointer in c/c++?

in C code I'm stuck to pass an array of struct to a function, here's the code that resembles my problem:
typedef struct
{
int x;
int y;
char *str1;
char *str2;
}Struct1;
void processFromStruct1(Struct1 *content[]);
int main()
{
Struct1 mydata[]=
{ {1,1,"black","cat"},
{4,5,"red","bird"},
{6,7,"brown","fox"},
};
processFromStruct1(mydata);//how?!?? can't find correct syntax
return 0;
}
void processFromStruct1(Struct1 *content[])
{
printf("%s", content[1]->str1);// if I want to print 'red', is this right?
...
}
Compile error in msvc is something like this:
error C2664: 'processFromStruct1' : cannot convert parameter 1 from 'Struct1 [3]' to 'Struct1 *[]'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
How to solve this? tnx.
You almost had it, either this
void processFromStruct1(Struct1 *content);
or this
void processFromStruct1(Struct1 content[]);
and, as Alok points out in comments, change this
content[1]->str1
to this
content[1].str1
Your array is an array of structures, not an array of pointers, so once you select a particular structure with [1] there is no need to further dereference it.
Try
processFromStruct1( & mydata[ i ] ); // pass the address of i-th element of mydata array
and the method to
void processFromStruct1(Struct1 *content )
{
printf("%s", content->str1);
...
}
(2nd part already noted by John Knoeller and Alok).
John Knoeller gave the perfect syntax , I am trying to explain some basic things,
I hope that it willsolve your confusions in future.
This is very similar to passing pointer to a function in C.
Of course struct is also a pointer,
so we can pass the value in 2 ways
0. Via pointer
0. Via array ( since we are using array of struct )
so the problem is simple now ,
You have to give the data type of a variable as we do in normal pointers ,
here the data type is user-defined ( that means struct ) Struct1 then variable name,
that variable name can be pointer or array name ( choose a compatible way ).
This works for me. Changed structs to C++ style.
struct Struct1
{
int x;
int y;
char *str1;
char *str2;
};
Struct1 mydata[]=
{ {1,1,"black","cat"},
{4,5,"red","bird"},
{6,7,"brown","fox"},
};
void processFromStruct1(Struct1 content[]);
int main()
{
processFromStruct1(&mydata[1]);
return 0;
}
void processFromStruct1(Struct1 content[])
{
printf("%s",content->str1);
}
output: red
Perhaps a proper re-factoring from the future:
#include <stdio.h>
typedef struct
{
int x;
int y;
char *str1;
char *str2;
} struct_1;
static void proc_the_struct_1_arr (
const int count_ ,
// array arg declared with min number of arguments
// also can not be null
struct_1 content[ static count_ ]
)
{
for (unsigned j = 0; j < count_; ++j)
printf("x:%-4dy:%-4d%-12s%-12s\n", content[j].x,content[j].y,content[j].str1,content[j].str2);
}
int main( void )
{
struct_1 mydata[3]= {
{.str1 = "black", .str2 = "cat" },
{.str1 = "red", .str2 = "bird"},
{.str1 = "brown", .str2 = "fox" },
};
proc_the_struct_1_arr (3,mydata);
return 0;
}
Godbolt
Obviously proc_the_struct_1_arr declaration is interesting. That actually uses Variably Modified Types (VMT). That is a legal syntax only for array arguments.
That is not slower vs the pointer to array solution:
static void proc_the_struct_1_arr_pointer (
const int count_ ,
// array arg not declared with min
// required number of arguments
struct_1 (*arr_ptr)[ /* static no allowed here */ count_ ]
);
I assume the compiler "rewrites" the above to the array pointer, anyway. On the second option arr_ptr can be a null argument.
You can try the prototype as void processFromStruct1(Struct1 content[]); and then the declaration should be like void processFromStruct1(Struct1 content[]).

Returning a void pointer to a constant object in C

I'm writing an access function which returns a pointer to an internal buffer and I'd like to hint to users of my function that they shouldn't update the object that's pointed to. A very contrived example would be:
void myAccessFunc(bool string, void* p, size_t* len)
{
static const char* s = "aha!";
static const int i = 123;
if (string) {
*(char**)p = &s;
*len = strlen(s);
}
else {
*(int**)p = &i;
*len = sizeof(i);
}
}
char* s;
size_t bytes;
myAccessFunc(true,&s, &bytes);
printf("Got '%s'\n", s);
Yes, I know that looks flakey.
What I want to prevent is:
char* s;
size_t bytes;
myAccessFunc(true,&s,&bytes);
s[4] = '?';
I know I can't completely prevent it but I'd at least like the compiler warning to hint to a user that they shouldn't be doing that. If they cast my pointer, then that's their problem. Is there some combination of const and void and * that will do this? I tried something like:
void myAccessFunc(bool string, const void** p, size_t* len);
but it seemed do away with the voidness of the pointer so a caller had to do:
const void* p;
size_t bytes;
myAccessFunc(true, &p, &bytes);
or
const char* s;
size_t bytes;
myAccessFunc(true, (const void**)&s, &bytes);
and couldn't do:
const int * ip;
const char* s;
size_t bytes;
myAccessFunc(true, &s, &bytes);
myAccessFunc(false, &i, &bytes);
I finally came around to:
const void* myAccessFunc(bool string, size_t* len);
and if the user does:
char* p = myAcccessFunc(true,&bytes);
the compiler (GCC, at least), does complain about throwing away the qualifier.
It would be best to do something like:
const void * myAccessFunc();
Where you return the pointer to the internals, this is a bit more natural than passing it as an out parameter.
If you were to pass it as an out parameter, you would want:
void myAccessFunc(const void **p);
which prevents them from doing this accidentally:
void *p; /* error: must be 'const void *p;' */
myAccessFunc(&p);
You have two things you can do:
Return a const void*
Write some documentation for your API telling the users not to modify the returned value
With that said, any API user who decides to try and muck with a pointer like that deserves what they get :P.
Preventing is impossible, since you can cast away constness. If you make your function parameter const, you'll have to cast it away yourself inside the function. You'd also be lying to anyone using your function and could cause all sorts of fun bugs.
You could try returning a pointer instead. Then you'd at least not be violating your own const. That may not be appropriate in this case though.
Returning a pointer would be best, but if you absolutely need to make it an out parameter, you could use a struct as an intermediary:
typedef struct _ptr_holder {
const void* ptr;
} ptr_holder;
void myAccessFunc( bool string, ptr_holder* ptr ) {
...
}
ptr_holder s;
myAccessFunc(true,&s);
printf("Got '%s'\n", s.ptr);
It's hokey, but it should do the trick
So you want to prevent modification of via the pointer you return? Try this:
const void* myAccessFunc(bool string);
What is wrong with this? If you are going to vote down a valid answer, please leave a comment.
If you are writing a C library where you don't want to expose some internal data-structure it can be good to go an extra route and hide implementation with a unspecified struct typedef. This is also called an opaque types
Example:
In my_interface.h
#ifndef __MYINTERFACE_H__
#define __MYINTERFACE_H__
/* The unspecified struct statement */
typedef struct s_my_data t_my_data;
t_my_data *new_my_data(int someInitializer);
void free_my_data(t_my_data *data);
int enter_my_data(t_my_data *data, int someDataToEnter);
const char *return_str_my_data(t_my_data *data);
#endif /* __MYINTERFACE_H__ */
In my_interface.c
#include <my_interface.h>
/* Keep struct in .c file */
struct s_my_data {
int length;
char *string;
};
t_my_data *new_my_data(int someInitializer)
{
/* the exercise */
}
void free_my_data(t_my_data *data)
{
/* the exercise */
}
int enter_my_data(t_my_data *data, int someDataToEnter)
{
/* the exercise */
}
const char *return_str_my_data(t_my_data *data)
{
/* the exercise */
}
Is this C or C++?
Why in the int case are you passing the pointer to a static const?
The interface is suspect.
Overload and get rid of the boolean in the interface:
void myAccessFunc( const char* * const p, size_t* len){
*p = "blahblahblah";
*len = 12;
}
void myAccessFunc( const int* * const ppI, size_t* len){
static const int i = 123;
*ppI = &i;
*len = 4;
}
Gets rid of the test too. Since the user knows true or false for the original function he knows which one to use. Strong typing is your friend. Gets rid of the class of errors where type and pointer are inconsistent...
BTW passing such control flags versus overloading is undesirable, especially so in small methods.

Resources