Accessing pointer variable as a pointer to a different type in C

非 Y 不嫁゛ 提交于 2019-12-24 19:48:22

问题


Is it good practice to access a pointer variable by dereferencing a pointer to a pointer, which points to a different type or void? Could this break strict aliasing rules? C and C++ have some differences in aliasing rules. In this question we focus on C. The other question considering C++ can be found here. In the following example a double* is accessed as a void*.

int create_buffer(void** ptr, ...)
{
    *ptr = malloc(...);
    ...
}

int main(void)
{
    double* buffer;

    // The problematic code is here, double**
    // is coerced to void**, which is later
    // dereferenced by the function
    create_buffer((void**)&buffer, ...);
    ...
}

Is the following any better:

// keeping void** just as an indicator in the interface
// that the pointer is pointing to a pointer to any type
// it could be replaced by just void*
int create_buffer(void** ptr, ...)
{
    void* result = malloc(...);
    memcpy((void*)ptr, &result, sizeof result);
}

回答1:


Not answering your question, but you could manoeuvrer around the uncertainties you mention by just doing well defined stuff like:

int main(void)
{
  double* buffer;

  {
    void * pv;
    create_buffer(&pv, ...);
    buffer = pv; /* C does not need any cast here. */
  }

  ...



回答2:


I would rather write it like this, assuming you use the "int" to return some useful information to the caller that it can't do without:

void *create_buffer(size_t n, int *otherInfo) {
    void *ptr = malloc(n);
    *otherInfo = 0;
    if (ptr) {
        // Do whatever other initialization is expected
        // memset(ptr, 0, n);
    } else {
        *otherInfo = -1;
    }
    return ptr;
}

int main(void)
{
    double* buffer;
    int code;

    /* cast is not required by language or compiler, 
       but I still find it useful when reading */
    buffer = (double *)create_buffer(SIZE_REQUIRED, &code);

    /* equality testing can be done either way. This way here,
       if you ever forget a =, will never compile anywhere. Nowadays
       many compilers are smart enough to catch it on their own anyway */
    if (NULL == buffer) {
        // Handle out of memory error or other problem
        switch(code) {
            case -1:
                fprintf(stderr, "Out of memory\n");
            ...
            default:
                fprintf(stderr, "Unexpected error %d\n", code);            
                break;
        }
    }
}


来源:https://stackoverflow.com/questions/56200050/accessing-pointer-variable-as-a-pointer-to-a-different-type-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!