In C, is it good form to use typedef for a pointer?

前端 未结 8 1682
野性不改
野性不改 2021-01-06 10:46

Consider the following C code:

typedef char * MYCHAR;
MYCHAR x;

My understanding is that the result would be that x is a pointer of type \"

相关标签:
8条回答
  • 2021-01-06 11:02

    Another way to look at it is from the perspective of types. A type defines the operations that are possible on that type, and the syntax to invokes these operations. From this perspective, MYCHAR is whatever it is. It is the programmers responsibility to know the operations allowed on it. If it is declared like the first example, then it supports the * operator. You can always name the identifier appropriately to clarify it's use.

    Other cases where it is useful to declare a type that is a pointer is when the nature of the parameter is opaque to the user (programmer). There may be APIs that want to return a pointer to the user, and expect the user to pass it back to the API at some other point. Like a opaque handle or a cookie, to be used by the API only internally. The user does not care about the nature of the parameter. It would make sense not to muddy the waters or expose its exact nature by exposing the * in the API.

    0 讨论(0)
  • 2021-01-06 11:03

    I don't particularly like typedef to a pointer, but there is one advantage to it. It removes confusion and common mistakes when you declare more than one pointer variable in a single declaration.

    typedef char *PSTR;
    ...
    PSTR str1, str2, str3;
    

    is arguably clearer than:

    char *str1, str2, str3;  // oops
    
    0 讨论(0)
  • 2021-01-06 11:12

    For an API it is not necessary to hide structure definitions and pointers behind "abstract" typedefs.

            /* This is part of the (hypothetical) WDBC- API
            ** It could be found in wdbc_api.h
            ** The struct connection and struct statement ar both incomplete types,
            ** but we are allowed to use pointers to incomplete types, as long as we don't
            ** dereference them.
             */
    struct connection *wdbc_connect (char *connection_string);
    int wdbc_disconnect (struct connection *con);
    int wdbc_prepare (struct connection * con, char *statement);
    
    int main(void)
    {
      struct connection *conn;
      struct statement *stmt;
      int rc;
    
      conn = wdbc_connect( "host='localhost' database='pisbak' username='wild' password='plasser'" );
      stmt = wdbc_prepare (conn, "Select id FROM users where name='wild'" );
    
      rc = wdbc_disconnect (conn);
    
      return 0;
    }
    

    The above fragment compiles fine. (but it fails to link, obviously)

    0 讨论(0)
  • I also think this is a matter of style/convention. In Apple's Core Graphics library they frequently "hide" the pointer and use a convention of appending "Ref" to the end of the type. So for example, CGImage * corresponds to CGImageRef. That way you still know it's a pointer reference.

    0 讨论(0)
  • 2021-01-06 11:24

    I would use pointer typedefs only in situations when the pointer nature of the resultant type is of no significance. For example, pointer typedef is justified when one wants to declare an opaque "handle" type which just happens to be implemented as a pointer, but is not supposed to be usable as a pointer by the user.

    typedef struct HashTableImpl *HashTable;
    /* 'struct HashTableImpl' is (or is supposed to be) an opaque type */
    

    In the above example, HashTable is a "handle" for a hash table. The user will receive that handle initially from, say, CreateHashTable function and pass it to, say, HashInsert function and such. The user is not supposed to care (or even know) that HashTable is a pointer.

    But in cases when the user is supposed to understand that the type is actually a pointer and is usable as a pointer, pointer typedefs are significantly obfuscating the code. I would avoid them. Declaring pointers explicitly makes code more readable.

    It is interesting to note that C standard library avoids such pointer typedefs. For example, FILE is obviously intended to be used as an opaque type, which means that the library could have defined it as typedef FILE <some pointer type> instead of making us to use FILE * all the time. But for some reason they decided not to.

    0 讨论(0)
  • 2021-01-06 11:25

    If the pointer is never meant to be dereferenced or otherwise manipulated directly -- IOW, you only pass it as an argument to an API -- then it's okay to hide the pointer behind a typedef.

    Otherwise, it's better to make the "pointerness" of the type explicit.

    0 讨论(0)
提交回复
热议问题