从模块的外部上下文中正确隐藏函数

Properly hiding functions from the external context of the module

我正在尝试以面向对象的方式在 C 中实现信息隐藏。由于 C 显然不提供访问修饰符,例如 public、private 和 protected,我想出的解决方案是在 * 中定义一个抽象数据类型(哪些属性在外部不可见) .c 文件,并在相应的头文件中放入一个仅引用此新数据类型的typedef。

头文件还包含我的 public 函数的原型,因此用作此数据类型的 public 接口。 还有另一个头文件,其中列出了我不希望在正常情况下可见的受保护函数。 *.c 文件随后包含每个函数的实现,包括两个头文件中均未列出的函数。这些是我的私人功能。

LinkedList.h

#ifndef LINKEDLIST_H_
#define LINKEDLIST_H_

typedef struct LinkedList LinkedList;

LinkedList* newLinkedList();

#endif

LinkedList_protected.h

#ifndef LINKEDLIST_PROTECTED_H_
#define LINKEDLIST_PROTECTED_H_

#include "Node.h"
#include "LinkedList.h"

Node* getFirstNode(LinkedList* self);

Node* getLastNode(LinkedList* self);

#endif

LinkedList.c

#include "LinkedList.h"
#include "LinkedList_protected.h"
#include "Node.h"

// PRIVATE

struct LinkedList {

    Node* first;
    Node* last;
    unsigned int nodesNo;

};

void privateTest() {

    printf("Test");

}

// PROTECTED

Node* getFirstNode(LinkedList* self) {

    return self->first;
}

Node* getLastNode(LinkedList* self) {

    return self->last;

}

// PUBLIC

LinkedList* newLinkedList() {

    LinkedList* self = malloc(sizeof(LinkedList));

    self->first = NULL;
    self->last = NULL;

    self->nodesNo = 0;

    return self;

}

这似乎可行:尝试访问另一个模块中 LinkedList 的属性时出现错误 ("dereferencing pointer to incomplete type"),这正是我想要的。但是,引用私有甚至受保护的函数只会给我一个 "implicit declaration" 警告。这是为什么?我应该担心吗?另外,这个解决方案安全吗,是否可以改进?

C 是一门非常古老的语言。发明计算机时,速度很慢且内存很少,cpu 电源甚至磁盘 space。 CPU 时间也是要花钱的。必须包含 headers、解析它们并记住所有声明的函数,这会消耗实际成本。

因此,为了简化事情,编译器假设如果您调用一个函数,该函数将存在并采用您在调用时使用的参数类型,并且它将 return int。那是 "implicit declaration"。只需调用该函数即可隐式声明它。此功能至今存在。

所以编译器并不是以某种方式看到了那些 protected/private 函数,而是简单地盲目地假设它们存在,并且令人惊讶的是,当你稍后 link 将 object 文件放在一起时他们有。

查看您的编译器文档,了解如何将此警告变为错误。虽然完全合法,但它是一个非常危险的特性(隐式声明本质上会跳过任何类型检查,并且对于任何非 returning 的东西都会失败),现在你真的不应该使用这个特性。当有人试图使用它时编译失败似乎是你想要的。