I have an opaque type in my library defined as:
typedef struct MyOpaqueType* MyType; // easier to type for client code
I can't pass a pointer-to-const struct around using the typedef, so some functions look like:
void UsePointerToConst ( const struct MyOpaqueType * )
instead of:
void UserPointerToConst( const MyType ) // can't use, is really constant pointer
So, given this, I have two questions: Is the struct keyword in the parameter list only necessary in C? Is there a better way to do this? Should I create a typedef such as:
typedef const struct MyOpaqueType* ConstantMyType; ?
Is the struct keyword in the parameter list only necessary in C?
Yes. See Jens Gustedt's answer.
Is there a better way to do this?
Just typedef the struct, not the pointer. This is better because
typedef instead of one for each of {MyOpaqueType, MyOpaqueType *, MyOpaqueType const *, MyOpaqueType *const and MyOpaqueType const *const} and all variants involving restrict (which doesn't exist in C++),FILE *).There's also no danger; when someone forgets the *, they get a compiler error.
In C++ a typedef of the same name as a struct is assumed as long as there is no other identifier with that name. So something like a function stat that receives a struct stat* as an argument:
int stat(const char *path, struct stat *buf);
is even allowed in C++. (This is a real world example.)
So you are always better of with forward declarations like
typedef struct toto toto;
which reserves the token toto in the identifier and in the struct name space. Then you can have your function interface declared for C and C++. But don't forget the extern "C" if you want to access it from C, too.
See also: this answer on SO and struct tags are not identifiers in C++.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With