简体   繁体   English

function 参数中的 struct 关键字和 const 正确性

[英]struct keyword in function parameter, and const-correctness

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:我不能使用 typedef 传递指向 const 结构的指针,所以一些函数看起来像:

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?所以,鉴于此,我有两个问题:参数列表中的 struct 关键字是否仅在 C 中需要? Is there a better way to do this?有一个更好的方法吗? Should I create a typedef such as:我应该创建一个typedef,例如:

typedef const struct MyOpaqueType* ConstantMyType; ?

Is the struct keyword in the parameter list only necessary in C?参数列表中的struct关键字是不是只有C才需要?

Yes.是的。 See Jens Gustedt's answer.请参阅 Jens Gustedt 的回答。

Is there a better way to do this?有一个更好的方法吗?

Just typedef the struct, not the pointer.只需typedef结构,而不是指针。 This is better because这更好,因为

  • you only need one 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++),您只需要一个typedef而不是 { MyOpaqueTypeMyOpaqueType *MyOpaqueType const *MyOpaqueType *constMyOpaqueType const *const } 以及所有涉及restrict的变体(在 C++ 中不存在),
  • it's clear to the user that pointer semantics apply, ie, passing the datatype around is really a matter of pointer copying (no performance worries), users are less likely to forget cleaning up after use, C++ users may use smart pointers, and用户很清楚指针语义适用,即传递数据类型实际上是指针复制的问题(无需担心性能),用户不太可能在使用后忘记清理,C++ 用户可以使用智能指针,并且
  • it's a common C convention (think FILE * ).这是一个常见的 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.在 C++ 中,只要没有具有该名称的其他标识符,就会假定与struct同名的typedef So something like a function stat that receives a struct stat* as an argument:所以类似于 function stat接收struct stat*作为参数:

int stat(const char *path, struct stat *buf);

is even allowed in C++. 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.它将toto令牌保留在标识符和结构名称空间中。 Then you can have your function interface declared for C and C++.然后您可以为 C 和 C++ 声明您的 function 接口。 But don't forget the extern "C" if you want to access it from C, too.但是,如果您也想从 C 访问它,请不要忘记extern "C"

See also: this answer on SO and struct tags are not identifiers in C++ .另请参阅: 关于 SO 和结构标签的这个答案不是 C++ 中的标识符

You don't need the typedef at all in C++. C++ 中根本不需要 typedef。 Just use a forward declaration:只需使用前向声明:

struct MyType;

Then pass around MyType const * , MyType * , MyType const & etc as and when required.然后在需要时传递MyType const *MyType *MyType const &等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM