函数参数中的struct关键字和const-correctness

时间:2011-06-29 19:36:36

标签: c++ c const-correctness

我的库中有一个opaque类型定义为:

typedef struct MyOpaqueType* MyType;  // easier to type for client code

我不能使用typedef传递一个指向const的指针结构,所以有些函数看起来像:

void UsePointerToConst ( const struct MyOpaqueType * )

而不是:

void UserPointerToConst( const MyType ) // can't use, is really constant pointer

所以,鉴于此,我有两个问题: 参数列表中的struct关键字只在C中是必需的吗? 有一个更好的方法吗?我应该创建一个typedef,例如:

typedef const struct MyOpaqueType* ConstantMyType; ?

3 个答案:

答案 0 :(得分:5)

  

参数列表中的struct关键字是否仅在C?

中是必需的

是。见Jens Gustedt的回答。

  

有更好的方法吗?

只需typedef结构,而不是指针。这更好,因为

  • 每个{typedefMyOpaqueTypeMyOpaqueType *MyOpaqueType const *MyOpaqueType *const}只需要一个MyOpaqueType const *const而不是一个{}涉及restrict的所有变体(在C ++中不存在),
  • 用户很清楚指针语义是否适用,即传递数据类型实际上是指针复制的问题(没有性能担忧),用户不太可能忘记使用后清理,C ++用户可能会使用智能指针,和
  • 这是一个常见的C约定(想想FILE *)。

也没有危险;当有人忘记*时,他们会收到编译错误。

答案 1 :(得分:3)

在C ++中,只要没有具有该名称的其他标识符,就会假定typedefstruct同名。所以类似函数stat接收struct stat*作为参数:

int stat(const char *path, struct stat *buf);
在C ++中甚至允许

。 (这是一个现实世界的例子。)

所以你总是更好地使用像

这样的前向声明
typedef struct toto toto;

在标识符和结构名称空间中保留标记toto。然后,您可以为C和C ++声明您的函数接口。但是如果你想从C语言访问它,也不要忘记extern "C"

另请参阅:this answer on SOstruct tags are not identifiers in C++

答案 2 :(得分:2)

在C ++中根本不需要typedef。只需使用前瞻声明:

struct MyType;

然后在需要时传递MyType const *MyType *MyType const &等。