如何检查C中不同函数的调用顺序
为了将某个变量MyVariable设置为TRUE,我必须检查系统中是否遵守了特定的函数调用顺序。 例如,我在系统中有不同的功能:如何检查C中不同函数的调用顺序,c,C,为了将某个变量MyVariable设置为TRUE,我必须检查系统中是否遵守了特定的函数调用顺序。 例如,我在系统中有不同的功能: uint8 myFunction1() { if (...) { return NOT_OK } else { return OK } } uint8 myFunction2() { if (...) { return NOT_OK } else
uint8 myFunction1()
{
if (...)
{
return NOT_OK
}
else
{
return OK
}
}
uint8 myFunction2()
{
if (...)
{
return NOT_OK
}
else
{
return OK
}
}
uint8 myFunction3()
{
if (...)
{
return NOT_OK
}
else
{
return OK
}
}
仅当满足以下条件时,MyVariable=TRUE:
OK==myFunction1
OK==myFunction2
OK==myFunction3
确切地说,这个呼叫命令得到了尊重。
如何在C中检查调用顺序,但不涉及函数体,如设置一些标志等
我还是初学者,正在尝试C:
谢谢 没有直接和可移植的方法。也就是说,调试器擅长在到达函数时中断执行流,因此您可以使用调试器,或者在调用函数时使用调试函数发出警告 或者,一些链接器允许隐藏一些标识符并替换它们,因此,使用自定义和高级链接选项,您可以将所有对这些函数的调用替换为对自定义包装器的调用。但在这里,它只对特定的实现有意义,所以它也不是C方式
无论如何,这是一个如此不寻常的要求,我无法想象背后的实际理由。也许你可以提供更多关于你真正问题的背景…这几乎肯定是一个XY问题。也就是说,您认为保存调用顺序是解决实际问题的方法,但您的实际问题可能是首先要确保不会以错误的顺序调用函数 所以解决这个问题最正确的方法就是重新设计程序。有人提到状态机是一种解决方案。另一种解决方案可能类似于函数指针数组,这是状态机的常见实现 也就是说,你可以做一些人工的事情来跟踪通话顺序,尽管我并不推荐这样做。例如:
#define CALL_ORDER_N 3
const char* call_order [CALL_ORDER_N] = {NULL};
size_t call_order_i = 0;
static void save_call (const char* func)
{
call_order[call_order_i] = func;
call_order_i++;
if(call_order_i == CALL_ORDER_N)
{
call_order_i = 0;
}
}
其中调用顺序将最后3个函数调用保存为字符串文本的指针。函数save_调用通过从每个函数向数组传递_func__常量来更新此数组__func_uu保证像静态常量char[]一样工作,因此这是安全的。你可以这样做:
void myFunction1 (void)
{
save_call(__func__);
...
}
void myFunction2 (void)
{
save_call(__func__);
...
}
void myFunction3 (void)
{
save_call(__func__);
...
}
然后查看通话顺序是否正确:
static bool is_call_order_ok (void)
{
const char* expected_order [CALL_ORDER_N] =
{
"myFunction1",
"myFunction2",
"myFunction3"
};
size_t co_i = call_order_i;
for(size_t i=0; i<CALL_ORDER_N; i++)
{
if(strcmp(call_order[co_i], expected_order[i])==0)
{
co_i++;
if(co_i == CALL_ORDER_N)
{
co_i = 0;
}
}
else
{
return false;
}
}
return true;
}
当然,save_调用应该正确地放置在自己的.h/.c文件对中。您知道状态机的概念吗?1.将函数包装到自定义函数中,在其中使用时间戳设置标志。2.设置myVariable时,比较时间戳和函数返回。3.这是C。没有其他方法可以自己实现。通常,随着程序的增长,您可能希望查看类似于在源文件中绘制控制流的图表。谢谢您提供的信息。但是调试程序在调试时非常棒。我需要在系统运行期间检查条件。更准确地说:我的要求是,只有在调用第一个myFunction1而不是myFunction2和myFunction3时,我才能在系统中更改为特定状态。
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define CALL_ORDER_N 3
const char* call_order [CALL_ORDER_N] = {NULL};
size_t call_order_i = 0;
static void save_call (const char* func)
{
call_order[call_order_i] = func;
call_order_i++;
if(call_order_i == CALL_ORDER_N)
{
call_order_i = 0;
}
}
static bool is_call_order_ok (void)
{
const char* expected_order [CALL_ORDER_N] =
{
"myFunction1",
"myFunction2",
"myFunction3"
};
size_t co_i = call_order_i;
for(size_t i=0; i<CALL_ORDER_N; i++)
{
if(strcmp(call_order[co_i], expected_order[i])==0)
{
co_i++;
if(co_i == CALL_ORDER_N)
{
co_i = 0;
}
}
else
{
return false;
}
}
return true;
}
void myFunction1 (void)
{
save_call(__func__);
}
void myFunction2 (void)
{
save_call(__func__);
}
void myFunction3 (void)
{
save_call(__func__);
}
int main (void)
{
printf("Call 1,2,3: ");
myFunction1();
myFunction2();
myFunction3();
printf(is_call_order_ok() ? "Ok\n" : "Failed\n");
printf("Call 3,2,1: ");
myFunction3();
myFunction2();
myFunction1();
printf(is_call_order_ok() ? "Ok\n" : "Failed\n");
printf("Call 1,1,1: ");
myFunction1();
myFunction1();
myFunction1();
printf(is_call_order_ok() ? "Ok\n" : "Failed\n");
return 0;
}
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define CALL_ORDER_N 3
static bool save_call (const char* func, bool verify)
{
bool result;
static const char* call_order [CALL_ORDER_N] = {NULL};
static size_t call_order_i = 0;
static const char* expected_order [CALL_ORDER_N] = {NULL};
size_t i = call_order_i;
if(verify) // special case, verify the order
{
for(size_t expected=0; expected<CALL_ORDER_N; expected++)
{
if(call_order[i] == expected_order[expected])
{
i++;
if(i == CALL_ORDER_N)
{
i = 0;
}
}
else
{
return false;
}
}
return true;
}
if(expected_order[i] == NULL) // register order of calls
{
expected_order[i] = func;
result = true;
}
else // save calls
{
call_order[i] = func;
result = false;
}
call_order_i++;
if(call_order_i == CALL_ORDER_N)
{
call_order_i = 0;
}
return result;
}
void myFunction1 (void)
{
if(save_call(__func__, false))
return ;
printf("Execute stuff in %s.\n", __func__);
}
void myFunction2 (void)
{
if(save_call(__func__, false))
return ;
printf("Execute stuff in %s.\n", __func__);
}
void myFunction3 (void)
{
if(save_call(__func__, false))
return ;
printf("Execute stuff in %s.\n", __func__);
}
int main (void)
{
/* register call order: */
myFunction1();
myFunction2();
myFunction3();
printf("Call 1,2,3:\n");
myFunction1();
myFunction2();
myFunction3();
printf(save_call(NULL, true) ? "Ok\n\n" : "Failed\n\n");
printf("Call 3,2,1:\n");
myFunction3();
myFunction2();
myFunction1();
printf(save_call(NULL, true) ? "Ok\n\n" : "Failed\n\n");
printf("Call 1,1,1:\n");
myFunction1();
myFunction1();
myFunction1();
printf(save_call(NULL, true) ? "Ok\n\n" : "Failed\n\n");
return 0;
}