测试不透明类型的内部结构

问题描述 投票:0回答:2

第一:C 中的不透明指针是什么?

现在,当谈到测试这种类型时,我知道有 3 种方法:

  1. 将源文件(包含类型定义及其使用的函数)目录包含到测试源文件中。 (这是最简单的,但经常在没有任何理由的情况下劝阻)。

  2. 使公共访问器有条件可用(即,仅当在包含其标头之前定义了

    LIB_TEST
    时)。

  3. 创建一个单独的“lib-test.h”头文件,其中包含公共访问器。

最后两个避免使访问器成为公共 API 的一部分(我们讨论的是客户端无权了解有关不透明类型内部的任何信息,并且不应提供任何访问器的情况)。

C 中常用的方法(或好的方法)是什么?一种方式比另一种方式有更多的优点/缺点吗?

举个例子,假设我有这个

struct

typedef struct arena {
    size_t count;
    size_t capacity;
    size_t current;
    size_t last_alloc_size;
    M_Pool *pools[];
} Arena;

以及与之相关的功能:

void arena_reset(Arena *arena)
{
    for (size_t i = 0; i < arena->count; ++i) {
        arena->pools[i]->offset = 0;
    }
    arena->current = 1;
}

现在我想断言

arena_reset()
实际上已经将所有arena的
offset
pools
字段设置为0,并将arena的
current
字段设置为1。包括这个库提供的API(头文件)是没有什么好处,因为只提供了结构类型的前向声明,并且无法访问其成员。

c testing header-files
2个回答
0
投票

如果您想测试源模块的内部细节(即声明为

static
的函数或对象,或仅在源模块中定义的
struct
定义),这是极少数有意义的情况之一
 #include
.c 文件。

例如,如果上面的结构和函数驻留在 arena.c 中,您的测试模块可以执行如下操作:

#include <stdlib.h>
#include "arena.c"

void test_arena_reset()
{
    int pool_cnt = 3;
    Arena *p = malloc(sizeof *p + (pool_cnt * sizeof(M_Pool));
    p->count = pool_cnt;
    for (int i = 0; i < pool_cnt; i++) {
        p->pools[i]->offset = 1;
    }
    p->current = 0;

    arena_reset(p);

    assert(p->current == 1);
    for (int i = 0; i < pool_cnt; i++) {
        assert(p->pools[i]->offset == 0);
    }
}

0
投票

使类型定义可用于多个翻译单元的传统机制是将它们放在标头中,每个需要定义的 TU

#include
。不透明类型没有什么不同。这只是一个问题:该类型对于哪些翻译单元是不透明的,对于哪些翻译单元不是不透明的。

如果您想提供源代码中包含的测试来穿透不透明类型的不透明性,请将类型定义放在私有标头中。让那些应该能够看到类型定义的源文件包含该标头。其他人则不然。如果项目是一个库,则私有标头不会与常规库标头一起安装。

这与问题中提出的所有选项都不同,尽管它与(1)和(3)有相似之处。特别要注意的是

  • 所讨论的私有标头将是真正的标头——没有函数定义。它将提供以前不透明类型的定义,而不是源文件来执行此操作。

  • 除了提供的任何访问器函数外,没有定义或需要任何访问器函数。

© www.soinside.com 2019 - 2024. All rights reserved.