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

jer*_*iff 2 c macros time

从对此答案的评论:/sf/answers/32179311/

我尝试创建一个宏函数,该函数将函数作为参数并使用 对其进行计时clock()。但是,我不断收到一条错误消息,指出该消息start未声明,而且我无法弄清楚,因为我确实在宏的前面声明了它

(这一切都在我的代码中的同一行上,以防产生影响;为了便于阅读,我将其分成两行):

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

Jon*_*ler 5

直接的问题是 \xe2\x80\x94 之后的冒号timing(a)需要在其前面有一个标签,但您不能在变量定义上使用标签,因此您需要丢失冒号:

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

您可能还应该避免污染函数的名称空间。执行此操作的经典方法是循环do { \xe2\x80\xa6 } while (0)

\n\n
#define timing(a) \\\n    do { \\\n        clock_t start = clock(); \\\n        a; \\\n        clock_t stop = clock(); \\\n        printf("Elapsed: %f seconds\\n", (double)(stop - start) / CLOCKS_PER_SEC); \\\n    } while (0)\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
if (do_it_this_way)\n    timing(some_func(1, 37, 91));\nelse\n    timing(some_func(2, 41, 87));\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您仅{ \xe2\x80\xa6 }在宏主体周围使用,则会生成错误(因为后面的分号91意味着 else 不属于if扩展为的任何 \xe2\x80\x94 if (do_it_this_way) { \xe2\x80\xa6 }; else \xe2\x80\xa6)。

\n\n

我并不是特别热衷于这种技术。我使用逻辑上不透明的类型 ,Clock具有支持功能,例如:

\n\n
extern void  clk_init(Clock *clk);\nextern void  clk_start(Clock *clk);\nextern void  clk_stop(Clock *clk);\nextern char *clk_elapsed_ms(Clock *clk, char *buffer, size_t buflen);\nextern char *clk_elapsed_us(Clock *clk, char *buffer, size_t buflen);\nextern char *clk_elapsed_ns(Clock *clk, char *buffer, size_t buflen);\n
Run Code Online (Sandbox Code Playgroud)\n\n

调用代码创建并初始化 a Clock,然后可以在循环之前启动时钟,在循环之后停止时钟,并在空闲时分析经过的时间。您可以在 Github https://github.com/jleffler/soq/tree/master/src/libsoqtimer.c和中找到此代码timer.h。如果您使用术语 \' \' 搜索 SO,您可以找到使用它的示例user:15168 clk_elapsed_us(例如,如何环绕范围?)。

\n