额,这个问题困扰我很长一段时间了...
- #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )
- {
- List_t * const pxConstList = ( pxList );
- /* Increment the index to the next item and return the item, ensuring */
- /* we don't return the marker used at the end of the list. */
- ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;
- if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )
- {
- ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;
- }
- ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;
- }
复制代码
这是FreeRTOS的一段源码,小弟如果自己实现这段功能,我肯定(不加思索)使用函数.但既然源码使用宏(源码这样用,应该是有它的道理),小弟不明白,恳请指教...
问题1: 使用宏相比较函数有哪些优点和缺点?
问题2: (抛开个人习惯问题)在什么情况下应当使用函数,什么情况下应当使用宏?
个人理解使用函数的优点:
1> 会对参数类型进行检查,容易避免基本的语法错误...
2> 可能(至少对于我这种)会提高代码的可读性...
个人理解使用宏的优点:
1> 使用宏,实际上是代码替换,最直观的好处就是减少函数调用(不会额外增加堆栈深度)...
2> 宏的替换是在编译期间进行的,不会增加程序运行期间的负担...
用函数和用宏没什么大区别,毕竟宏只是字面值替换,就是在自动“Ctrl + C/V"源代码。
当然,宏的字面值替换带来了更大的灵活性。
宏附加的问题:
返回值:大段代码的话,不使用编译器扩展,用宏只能实现成void macro(bla bla)这样的形式。
参数类型:其实没关系,宏里赋值一次就行,和函数实参赋值到形参没区别。
宏字面值展开导致“强制inline”的代码膨胀,宏的特 {MOD}么,可以在头文件里解决,甚至可以根据情况来,灵活性更大。
缺点就是宏展开不好调试……编译器报的是展开后的错。
对头,宏过于复杂的话编译的时候出错真的令人无语,调试的时候更是令人绝望
没办法,
一直以来,FreeRTOS 的 code style 都是那么的独特。
一周热门 更多>