C 稳健函数

C 稳健函数,c,embedded,C,Embedded,我有两个函数用于分配和释放计时器 Allocate timer分配一个计时器,并向已分配的计时器返回一个int int allocate_timer(void) { int count = 0; int allocated = 0; /*Loop to find the first timer that is not allocated*/ for(count = 0; count< ARRAY_SIZE; count++) { if

我有两个函数用于分配和释放计时器

Allocate timer分配一个计时器,并向已分配的计时器返回一个int

int allocate_timer(void)
{
  int count = 0;
  int allocated = 0;
    /*Loop to find the first timer that is not allocated*/
    for(count = 0; count< ARRAY_SIZE; count++)
    {
            if(allocated_timers[count] == '0')
            {
                    /*When the next timer available timer is found it is set to allocated and timer is set to zero*/
                    allocated_timers[count] = '1';
                    timers[count] = 0;
                    break;
            }

            else if(allocated > ARRAY_SIZE - 1)
            {
                printf("No timers available\n");
                exit(0);

            }

            else
            {
                allocated++;
            }

    }
    /*Position of the allocated timer is returned*/
    return count;
}
我无法让它们变得比现在更健壮。
关于如何使它们变得更好,有什么建议吗?

分配的变量
始终等于
计数
(因此可以删除),并且在
分配的计时器
数组中使用
'0'
'1'
作为值可能会造成混淆。通常是
0
1

它们都不会影响代码的健壮性,但是代码越容易理解,它对将来的修改就越健壮

当您有两个“并行”数组时,就像您在这里所做的那样,每个计时器在
计时器中有一个条目,在
分配的\u计时器中有一个对应的条目,值得考虑是否最好使用一个
结构
和两个成员的单个数组(在本例中,可能命名为
value
assigned
)。有时并不更好,但通常它有助于理解代码,因为读者不必发现并记住这两个数组是密切相关的

deallocate\u one\u timer
在用作数组索引之前,如果它检查
position
是否在
0
ARRAY\u SIZE
的范围内,则可以稍微增强对调用方错误使用的鲁棒性。我不是说函数有责任进行这些检查,但它们有时有助于诊断其他地方的bug。您可以使用
assert
进行这样的非必要检查。
assert
有两个好处。首先,它自己记录检查不是此函数的责任来处理,只是您正在检查其他人做了他们应该做的事情。其次,您可以轻松地禁用p的非调试版本中的所有断言如果您需要使其更小或更快,请编程

类似地,如果释放了当前未分配的计时器,则退出时显示错误消息可能会有所帮助,因为这可能表明存在潜在问题。释放两次计时器的人可能会在分配计时器的其他人的任一侧执行此操作,这意味着其他人突然发现他们不再独占使用计时器r定时器

最后,设置
计时器[索引]
在分配和取消分配时都设置为0。这没有什么特别的错误,只是它混淆了哪个函数实际负责确保新分配的计时器具有正确的初始值。取消分配函数无法执行任何操作,或者它可以将计时器设置为分配的计时器无法执行的值计时器保持(可能是-1,假设计时器从0开始上升),这样在调试时,您可以立即知道,如果您使用的计时器的值为-1,则表示出现了问题


最后,这段代码(显然)不是线程安全的,我认为这是一种非健壮性。编写不能在多线程程序中使用的代码没有什么害处,特别是在嵌入式系统中,这些系统甚至可能没有创建线程的能力。只要这是一个经过深思熟虑的决定,并且有文档记录。

分配的变量
总是e与
count
(因此可以删除)相等,在
分配的计时器数组中使用
'0'
'1'
作为值可能会造成混淆。通常是
0
1

它们都不会影响代码的健壮性,但是代码越容易理解,它对将来的修改就越健壮

当您有两个“并行”数组时,就像您在这里所做的那样,每个计时器在
计时器中有一个条目,在
分配的\u计时器中有一个对应的条目,值得考虑是否最好使用一个
结构
和两个成员的单个数组(在本例中,可能命名为
value
assigned
)。有时并不更好,但通常它有助于理解代码,因为读者不必发现并记住这两个数组是密切相关的

deallocate\u one\u timer
在用作数组索引之前,如果它检查
position
是否在
0
ARRAY\u SIZE
的范围内,则可以稍微增强对调用方错误使用的鲁棒性。我不是说函数有责任进行这些检查,但它们有时有助于诊断其他地方的bug。您可以使用
assert
进行这样的非必要检查。
assert
有两个好处。首先,它自己记录检查不是此函数的责任来处理,只是您正在检查其他人做了他们应该做的事情。其次,您可以轻松地禁用p的非调试版本中的所有断言如果您需要使其更小或更快,请编程

类似地,如果释放了当前未分配的计时器,则退出时显示错误消息可能会有所帮助,因为这可能表明存在潜在问题。释放两次计时器的人可能会在分配计时器的其他人的任一侧执行此操作,这意味着其他人突然发现他们不再独占使用计时器r定时器

最后,设置
计时器[索引]
在分配和取消分配时都设置为0。这没有什么特别的错误,只是它混淆了哪个函数实际负责确保新分配的计时器具有正确的初始值。取消分配函数无法执行任何操作,或者它可以将计时器设置为分配的计时器无法执行的值计时器保持(可能是-1,假设计时器从0开始上升),这样在调试时,您可以立即知道,如果您使用的计时器的值为-1,则表示出现了问题

最后是国际泳联
void deallocate_one_timer(int position)
{       
    if(TIMER_ALLOCATED == allocated_timers[position])
    {
            allocated_timers[position] = '0';
            timers[position] = 0;
    }
}
int allocate_timer(void)
{
    int count;

    for (count = 0; count < ARRAY_SIZE; count++)
    {
        if (allocated_timers[count] == '0')
        {
            allocated_timers[count] = '1';
            timers[count] = 0;
            return count;
        }
    }
    fprintf(stderr, "No timers available\n");
    exit(EXIT_FAILURE);
}