【问题标题】:Casting pthread's start_routine argument with a macro使用宏强制转换 pthread 的 start_routine 参数
【发布时间】:2012-01-20 05:17:55
【问题描述】:

我正在尝试理解我收到的一些代码。它的工作方式与pthread_create 类似:您将一个指向函数start_routine 的指针传递给它,该函数将指向void arg 的指针作为单个参数,以及参数指针本身,然后pthread_create 调用您的函数.

通常,如果start_routine 确实需要一个参数,它不需要void *,而是应该将arg 强制转换为指向某个结构的指针。过去,我的start_routines 编码是这样的:

void *my_start_routine(void *arg)
{
    struct my_struct *p = arg;
    // use p many times
}

但是,我刚刚收到代码,其中作者设置了一个宏来在每次使用 p 时进行转换:

void *my_start_routine(void *arg)
{
#define p ((struct my_struct *) arg)
    // use p many times

#undef p
}

我很难理解您为什么要这样做。但我认为这是故意的,因为它似乎比第一种方式更困难且不那么明显,而且作者在整个代码中都使用了类似的习语。是否有某种原因(性能或其他原因)更喜欢这里的宏?

【问题讨论】:

    标签: c macros pthreads


    【解决方案1】:

    你的成语更可取;在我看来,其他人的宏是可憎的,原因如下:

    • p 不是左值
    • 更改为arg 会影响p,这一点并不明显。
    • 调试器不知道p 是什么。
    • ...

    【讨论】:

    • 谢谢大家。这只是一个学生试图理解另一个学生的代码的例子——换句话说,盲人在引导盲人。我不知道的事情太多了,当我遇到无法解释的事情时,我永远无法弄清楚我是愚蠢的还是他们疯了。
    【解决方案2】:

    我能看到的唯一可能的区别是不会在堆栈上为 p 分配空间,但这是一个相当可疑的优化,因为它只在函数开始时完成一次,很可能是由编译器以任何方式优化。

    我现在倾向于只将预处理器用于非常简单的替换,因为宏可以更好地作为内联函数(或编译器进行自己的优化)和分组常量(如错误代码)更好地作为枚举。

    【讨论】:

    • 一个好的编译器也不会分配空间,而只是重用已经为参数保留的空间。
    猜你喜欢
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    相关资源
    最近更新 更多