简体   繁体   English

使用宏强制转换pthread的start_routine参数

[英]Casting pthread's start_routine argument with a macro

I'm trying to understand some code I've been given. 我正在尝试了解我收到的一些代码。 It works in a similar way to pthread_create : you pass it a pointer to a function start_routine which takes a pointer to void arg as the single argument, and the argument pointer itself, and then pthread_create calls your function. 它的工作方式与pthread_create相似:向它传递一个指向函数start_routine的指针,该函数将指向void arg的指针作为单个参数,并传递参数指针本身,然后pthread_create调用您的函数。

Generally, if start_routine actually needs an argument, it does not need a void * , but rather arg should be cast to a pointer to some struct. 通常,如果start_routine实际上需要一个参数,则不需要void * ,而应将arg转换为指向某个结构的指针。 In the past, I've coded my start_routine s like this: 过去,我已经将start_routine编写为:

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

However, I just received code where the author sets up a macro to do the cast every time p is used: 但是,我刚刚收到的代码中,作者每次使用p都会设置一个宏来进行强制转换:

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

#undef p
}

I'm having a hard time understanding why you'd want to do this. 我很难理解为什么要这么做。 But I assume it is deliberate, because it seems more difficult and less obvious than the first way, and the author uses similar idioms throughout the code. 但是我认为它是有意的,因为它看起来比第一种方法更困难且不那么明显,并且作者在整个代码中都使用了类似的习惯用法。 Is there some reason, performance or otherwise, to prefer the macro here? 是否出于某种原因(无论出于性能还是其他原因)更喜欢此处的宏?

Your idiom is preferable; 你的习惯是可取的。 the other person's with the macro is, in my opinion, an abomination, for reasons like: 在我看来,其他人使用该宏是可憎的,原因如下:

  • p is not an lvalue p不是左值
  • It's non-obvious that changes to arg affect p . 改变arg会影响p并非显而易见。
  • The debugger won't have any idea what p is. 调试器不会知道p是什么。
  • ... ...

The only possible difference I could see would be that no space would be allocated on the stack for p , but this is a rather dubious optimisation, since it's done only once at the start of the function, and may well be optimised out by the compiler any way. 我可能看到的唯一可能的区别是,不会在堆栈上为p分配空间,但这是一个相当可疑的优化,因为它在函数开始时只执行了一次,并且很可能会被编译器优化任何方式。

I tend to use the preprocessor only for very simple substitutions nowadays since macros can be better done as inline functions (or compilers doing their own optimisations) and grouped constants (like error codes) are better as enumerations. 如今,我倾向于仅将预处理器用于非常简单的替换,因为宏可以更好地完成,因为内联函数(或编译器进行自己的优化)和分组常量(例如错误代码)更好地作为枚举。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM