{"action":"created","issue":{"url":"https://api.github.com/repos/cesanta/v7/issues/531","labels_url":"https://api.github.com/repos/cesanta/v7/issues/531/labels{/name}","comments_url":"https://api.github.com/repos/cesanta/v7/issues/531/comments","events_url":"https://api.github.com/repos/cesanta/v7/issues/531/events","html_url":"https://github.com/cesanta/v7/issues/531","id":120570450,"number":531,"title":"Consider defining v7_t for struct v7*","user":{"login":"swisspol","id":627915,"avatar_url":"https://avatars.githubusercontent.com/u/627915?v=3","gravatar_id":"","url":"https://api.github.com/users/swisspol","html_url":"https://github.com/swisspol","followers_url":"https://api.github.com/users/swisspol/followers","following_url":"https://api.github.com/users/swisspol/following{/other_user}","gists_url":"https://api.github.com/users/swisspol/gists{/gist_id}","starred_url":"https://api.github.com/users/swisspol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swisspol/subscriptions","organizations_url":"https://api.github.com/users/swisspol/orgs","repos_url":"https://api.github.com/users/swisspol/repos","events_url":"https://api.github.com/users/swisspol/events{/privacy}","received_events_url":"https://api.github.com/users/swisspol/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-12-05T16:38:22Z","updated_at":"2015-12-06T16:26:57Z","closed_at":"2015-12-06T13:48:46Z","body":"It's kind of an anachronism to have to type `struct v7*` everywhere instead of a clean `v7_t` in 2015 :wink: "},"comment":{"url":"https://api.github.com/repos/cesanta/v7/issues/comments/162327077","html_url":"https://github.com/cesanta/v7/issues/531#issuecomment-162327077","issue_url":"https://api.github.com/repos/cesanta/v7/issues/531","id":162327077,"user":{"login":"swisspol","id":627915,"avatar_url":"https://avatars.githubusercontent.com/u/627915?v=3","gravatar_id":"","url":"https://api.github.com/users/swisspol","html_url":"https://github.com/swisspol","followers_url":"https://api.github.com/users/swisspol/followers","following_url":"https://api.github.com/users/swisspol/following{/other_user}","gists_url":"https://api.github.com/users/swisspol/gists{/gist_id}","starred_url":"https://api.github.com/users/swisspol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swisspol/subscriptions","organizations_url":"https://api.github.com/users/swisspol/orgs","repos_url":"https://api.github.com/users/swisspol/repos","events_url":"https://api.github.com/users/swisspol/events{/privacy}","received_events_url":"https://api.github.com/users/swisspol/received_events","type":"User","site_admin":false},"created_at":"2015-12-06T16:26:57Z","updated_at":"2015-12-06T16:26:57Z","body":"I don't know... This seems like 20 years old guidelines and the state of compilers and API design patterns have evolved significantly since then :smile: \r\n\r\nFurthermore it seems they argue against `typedef struct {} Foo` in headers, and are not talking about opaque private structures declared in public headers like `typedef struct v7* v7_t`.\r\n\r\nAFAIK the vast majority of C APIs have been using typedefs for opaque structures for a long time now: anything from POSIX `typedef struct _opaque_pthread_mutex_t __darwin_pthread_mutex_t` to pretty much the enter iOS / OS X stack and many system level APIs like libdispatch. Same on Linux (see GTK) and Windows.\r\n\r\n> Typedefs are problematic because they do not properly hide their underlying type;\r\n\r\n`typedef struct v7* v7_t;` in a public header certainly hides the underlying structure.\r\n\r\n> for example you need to know if the typedef is the structure itself or a pointer to the structure.\r\n\r\nYou don't need to know this when designing modern C APIs. It's just an opaque type returned by a constructor function, then passed to various APIs as-is and finally passed to a destructor function. It's irrelevant to the API clients if it's a scalar, a pointer, a pointer to a pointer or whatever.\r\n\r\n> In addition they must be declared exactly once, whereas an incomplete structure type can be mentioned as many times as necessary.\r\n\r\nYou can also declare `typedef struct v7* v7_t;` 10 times in 10 different headers in you want, this is totally supported by the C standard. Although typically you only put it in one header.\r\n\r\n> Typedefs are difficult to use in stand-alone header files: the header that defines the typedef must be included before the header that uses it, or by the header that uses it (which causes namespace pollution), or there must be a back-door mechanism for obtaining the typedef.\r\n\r\nSo yeah, you can have `void Foo(struct temp* bar);` in a header without having to declare `struct temp` at all before... If you have `void Foo(temp_t bar);`, you must declare `temp_t` before. I fail to see how that's a problem in real-life though :wink: \r\n\r\nAnyway, it's not a big deal either way, but v7 API certainly stands out among the vast majority of modern C APIs (and by modern I mean maybe anything in the past 10 years)."}}