Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 832
Chris Nelson Avatar asked Dec 06 '25 06:12

Chris Nelson


2 Answers

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);
like image 144
Greg Rogers Avatar answered Dec 07 '25 19:12

Greg Rogers


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.

like image 41
17 of 26 Avatar answered Dec 07 '25 21:12

17 of 26