Void pointers and char/strings

I have a class with a generic function and one void pointer ans an argument.

typedef void (*GFunc)(void*); //Function pointer for MenuItem

Now, the only case I had issues passing the pointer around was when I tried to write my error class that prints to the screen of my project. I wanted to allow for custom error/warning text to be put in when the class is instantiated, but when I typed in a string like "someString" as an argument I got the compiler error of invalid conversion from 'const void*' to 'void*' [-fpermissive]

This is obviously because the default behavior of double quotes is to generate a const char*, and then in the process of conversion it changes from char to void before realizing there's a const keyword.

I got around the issue by casting it like so: `(void*)"someString"

Now, I realize this is terrible, hacky, and probably exceedingly dangerous, but I wanted to know exactly how bad a sin I'm committing. It appears to work, and for all of my testing I can't find anything wrong, but I'm working on platform with around 4MB of memory so I don't know if I'm just not seeing the effects of memory fragmentation or if it's fine, just weird.

Is anyone familiar with what this will do to my poor little microcontroller?

If the argument to the function is only got getting data into the function you could just declare it 'const void *'. That would allow you to safely pass a 'const char *'.

1 Like

I'll look into it. I don't think having a const will work with some of my other systems, but' I'll do some testing to see if I can without breaking anything.

Thanks for the suggestion!

is typical for a generic function ptr that may require different arguments. in one case a char * is cast as a void * and in another case an int is cast as a void *.

the actual function then recasts from void * to char *, int *, ....

1 Like

That's what I've done with the ints, floats, other primitives, and my classes/structs. I just ran into a problem with the string notation since "someString" is a const char * by default, and I haven't verified if I can set the rest of the data to also have const pointers so the pattern matches.

Are you going to modify the data you point at? It is not OK with string literals (if you did not allocate a buffer in RAM for the text, hence the compiler warning you).

Remember to read type definition from right-to-left.

  • const void * p means “p points to some place that is const”: the memory can’t be changed using p. It is read only
  • void * const p means “p is a const pointer to a memory location that is not const”: you can’t change the pointer p itself, but you can change the data pointed
  • const void * const p means “p is a const pointer to a place in memory that is const”. So you can’t change the pointer p itself, nor can you change the data in memory.

I will be modifying the data, sometimes.

It's supposed to be a generic function for "Run this function with this variable when you press the button" so certain options contain:

  • A pointer to an integer, for brightness, control stick sensitivity, etc. This data would have to be mutable
  • A pointer to a custom class, for loading LED patterns. This requires that I set the pointer to a new set of data, and thus mutable.

To match const char* all of my data would need to be const, and since the primary goal of this system is to make a menu to adjust things on the fly (detached from a computer) that's counter-intuitive.

Maybe I can fiddle around with some sort of copy functions when I dereference the pointers in some cases, but it's something I have to check.

it's "just" a warning, so as long as you know what you do you'll be fine.

1 Like

Okay, thank you.

Yes. Why not put the string literal (which passes as a 'const char *' into a char array? Then, it will pass as a 'char *'.
Just be sure the function that receives it doesn't write beyond the end of the array.

All of this is set up inside a few overarching functions and would get destroyed unless I have some global pool of memory for every character string I use, which sounds like a nightmare to maintain since I can have up to 100 pages and test for all of them.

I can and probably should do that, but I'm putting it on the back burner until I have the program working in full. Right now, I just need it done, not perfectly safe.

I just want to know what problems I can expect from my dumb hack.

I guess, officially, you'd have to see what the language specification says. I imagine the resulting behavior of writing to a 'const' variable via a pointer whose 'const-ness' has been cast away is undefined.

Sounds like fun. Thanks for the insight.