如何使这个函数计时宏在C中工作?

如何使这个函数计时宏在C中工作?,c,time,macros,C,Time,Macros,从对该答案的评论中: 我试着制作一个宏函数,将函数作为参数,并使用时钟对其进行计时。但是,我一直收到一条错误消息,说start未声明,我无法理解它,因为我在宏的前面声明了它 在我的代码中,这都在同一行,以防它产生差异;为了便于阅读,我将其分为两行: #define timing(a): clock_t start = clock(); a; clock_t stop = clock(); printf("Elapsed: %f seconds\n", (double)(stop - start

从对该答案的评论中:

我试着制作一个宏函数,将函数作为参数,并使用时钟对其进行计时。但是,我一直收到一条错误消息,说start未声明,我无法理解它,因为我在宏的前面声明了它

在我的代码中,这都在同一行,以防它产生差异;为了便于阅读,我将其分为两行:

#define timing(a): clock_t start = clock(); a; clock_t stop = clock(); 
printf("Elapsed: %f seconds\n", (double)(stop - start) / CLOCKS_PER_SEC);

直接的问题是timinga后面的冒号-它希望在它前面加一个标签,但不能在变量定义上使用标签,因此需要丢失冒号:

#define timing(a) \
    clock_t start = clock(); \
    a; \
    clock_t stop = clock(); \
    printf("Elapsed: %f seconds\n", (double)(stop - start) / CLOCKS_PER_SEC);
您可能还应该避免污染函数的名称空间。执行此操作的经典方法是do{…}while 0循环:

这将创建一个语句块,即使在未受保护的if块中也可以合法使用该语句块:

如果在宏体周围使用{…},则会产生错误,因为91后面的分号表示else不属于任何If-扩展为If do_it_this_way{…};否则

我对这种技术不是特别感兴趣。我使用逻辑不透明类型Clock,并支持以下功能:

extern void  clk_init(Clock *clk);
extern void  clk_start(Clock *clk);
extern void  clk_stop(Clock *clk);
extern char *clk_elapsed_ms(Clock *clk, char *buffer, size_t buflen);
extern char *clk_elapsed_us(Clock *clk, char *buffer, size_t buflen);
extern char *clk_elapsed_ns(Clock *clk, char *buffer, size_t buflen);

调用代码创建并初始化时钟,然后可以在循环之前启动时钟,在循环之后停止时钟,并在空闲时分析经过的时间。您可以在Github的timer.c和timer.h中找到这段代码。如果您使用术语“user:15168 clk__us”进行搜索,您可以找到正在使用的示例,例如:

您不想在timinga中使用冒号:或者,如果您保留冒号,则必须使用标签计时功能1、2、3;所以你有一个冒号的标签。而且它是否在一条逻辑线上也很重要——你应该用反斜杠继续这条线,这样你做的事情就更清楚了。我不认为这是一个好的宏。此外,如果您计划在程序中的多个位置使用该宏,请将其包含在{}中,否则您将有多个停止和启动实例。@JonathanLeffler,谢谢,它起了作用,但您为什么说它可能不是一个好的宏?@DYZ,您的意思是{timingfunction}每次我使用它,或者用大括号括住宏本身的定义?如果你不介意的话,多个实例是什么意思?我主要想到OOP上下文中的实例,这可能不是你的意思,对吗?它取决于o/s-这就是为什么它需要隐藏的原因。如果它可用,clock_gettime和clock_单调可以提供纳秒分辨率,但不一定是纳秒精度。如果不可用,可能gettimeofday可用微秒分辨率,或ftime毫秒分辨率或时钟,因为您使用的是分辨率系统相关,或时间分辨率系统相关,或GetTickCount,或…嘿,挑剔很有趣。使用时钟基本上是便携式的,但是你得到的分辨率不一定很好。谢谢你的详细解释,这是非常有帮助的。
if (do_it_this_way)
    timing(some_func(1, 37, 91));
else
    timing(some_func(2, 41, 87));
extern void  clk_init(Clock *clk);
extern void  clk_start(Clock *clk);
extern void  clk_stop(Clock *clk);
extern char *clk_elapsed_ms(Clock *clk, char *buffer, size_t buflen);
extern char *clk_elapsed_us(Clock *clk, char *buffer, size_t buflen);
extern char *clk_elapsed_ns(Clock *clk, char *buffer, size_t buflen);