我正在编写一个访问函数,它返回一个指向内部缓冲区的指针,我想向我的函数用户暗示他们不应该更新指向的对象.一个非常人为的例子是:
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);
是的,我知道这看起来很好看.
我想要防止的是:
char* s; size_t bytes; myAccessFunc(true,&s,&bytes); s[4] = '?';
我知道我不能完全阻止它但我至少喜欢编译器警告提示用户他们不应该这样做.如果他们投了我的指针,那就是他们的问题.有没有const和void的组合和*会这样做?我尝试过类似的东西:
void myAccessFunc(bool string, const void** p, size_t* len);
但它似乎消除了指针的无效性,因此调用者必须这样做:
const void* p; size_t bytes; myAccessFunc(true, &p, &bytes);
要么
const char* s; size_t bytes; myAccessFunc(true, (const void**)&s, &bytes);
并且做不到:
const int * ip; const char* s; size_t bytes; myAccessFunc(true, &s, &bytes); myAccessFunc(false, &i, &bytes);
我终于到了:
const void* myAccessFunc(bool string, size_t* len);
如果用户这样做:
char* p = myAcccessFunc(true,&bytes);
编译器(至少是GCC)确实抱怨抛弃限定符.
最好做一些事情:
const void * myAccessFunc();
在返回指向内部的指针的地方,这比将其作为out参数传递更自然.
如果你将它作为out参数传递,你会想要:
void myAccessFunc(const void **p);
这可以防止他们意外地这样做:
void *p; /* error: must be 'const void *p;' */ myAccessFunc(&p);