我正在重构一个旧的C代码。代码完全没有分层架构(一切都被所有东西访问),我正试图改变它。
我想切断对结构成员的直接访问(至少现在写)并且只允许通过访问功能进行访问。是否有一些工具(或者可能是直接编译器)可以为我检查这条规则?
我需要这个,因为我维护一个分支,而上游并不关心代码质量。
答案 0 :(得分:1)
确保没有新代码直接访问结构的最佳方法是不使用完全封装使它们可用。这是以不再能够在堆栈上使用结构为代价的。您提供了一个分配结构的函数,另一个函数用于释放它,所有模块函数都接受指向结构的指针。但是,结构本身的定义是在C文件中,而不是头文件。另一个缺点是你可能需要编写很多函数来操作/查询结构。
我将从旧代码库中提供我使用此方法的代码段。标题包含:
#ifndef INC_QUEUE_H
#define INC_QUEUE_H
typedef enum {
QUE_OK,
QUE_BAD_PARAM,
QUE_NO_MEMORY,
QUE_SYS_ERROR
} QUE_RV;
typedef struct Queue_st Queue_t;
QUE_RV QUE_New(Queue_t **ppQueue);
QUE_RV QUE_Put(Queue_t *pQueue, int priority, void *pData);
QUE_RV QUE_Get(Queue_t *pQueue, int *priority, void **ppData);
void QUE_Free(Queue_t *pQueue);
#endif /* INC_QUEUE_H */
C文件定义了结构Queue_st
和函数的实现(经过大量修改以突出显示方法):
#include "queue.h"
#include "log.h"
#define QUE_INITIAL_CAPACITY 128
struct Queue_st {
/* SNIP: structure contents go here */
};
QUE_RV QUE_New(Queue_t **ppQueue)
{
QUE_RV rv;
*ppQueue = malloc(sizeof(Queue_t));
/* SNIP: Check malloc, Initialize the structure here ... */
return QUE_OK;
}
void QUE_Free(Queue_t *pQueue)
{
if (pQueue != NULL)
{
/* SNIP: Free contents of the structure before the free below... */
free(pQueue);
}
}
另一种方法是使用typedef struct StructName *StructHandle;
,并用StructHandle
替换API中的所有指针。少担忧*
。
编辑:如果你想要一些成员可见,有些则不可见,也可以扩展上述方法。在标题中,定义:
typedef struct StructPriv StructPriv;
typedef struct {
/* public members go here */
StructPriv *private;
} Struct;
Struct *STRUCT_Create();
void STRUCT_Free();
在C文件中,定义私有成员以及操纵它们的函数。
答案 1 :(得分:0)
我认为您可以在eclipse IDE中使用checkstyle或PMD。在这两个实用程序中,您都可以配置自己的规则。
答案 2 :(得分:0)
您可以使用我建议的以前的工具,或者这仅适用于C ++和开源。 Vera++
您可以使用Tcl编写自己的规则。