让宏'返回'一个值

bob*_*obo 19 c++ macros return-value

我正在使用宏,我认为它工作正常 -

#define CStrNullLastNL(str) {char* nl=strrchr(str,'\n'); if(nl){*nl=0;}}

因此它可以将字符串中的最后一个换行清零,实际上它用于在fgets保持不变时切断换行符.

所以,我想知道我是否可以从宏中"返回"一个值,因此它可以被称为

func( CStrNullLastNL( cstr ) ) ;

或者我必须写一个函数

Mik*_*one 31

对于宏"返回值",宏本身必须是一个表达式.您的宏是一个语句块,无法计算表达式.

你真的应该写一个inline函数.它将同样快速且可维护性更高.

  • ......在我上次说任何话一周后,一个downvote,没有解释。这在其他人身上经常发生吗?o_o (2认同)

Dan*_*vil 26

#define CStrNullLastNL(str) ({ \
    char* nl=strrchr(str,'\n');\
    if(nl){*nl=0;} \
    nl; \
})
Run Code Online (Sandbox Code Playgroud)

应该管用.

编辑:...在海湾合作委员会.

  • 我可能会补充说,这是一个有用的扩展. (7认同)
  • @jeffamaphone:当然没有.`({})`结构是GCC扩展. (4认同)
  • @jeffamaphone:当然不便携.毕竟,这就是"扩展"的定义.:) (2认同)
  • ({ }) 构造究竟做了什么?评估最后一个语句? (2认同)
  • @bobobobo是的,它会评估最后一个语句.请记住,括号()和花括号{}都是必需的. (2认同)

i_a*_*orf 6

宏不返回值.宏告诉预处理器替换#define后面的东西后面的东西#define.结果必须是有效的C++.

您要求的是如何使以下有效:

func( {char* nl=strrchr(str,'\n'); if(nl){*nl=0;}} );
Run Code Online (Sandbox Code Playgroud)

除了让它成为一个真正的函数调用之外,我想不出一个好的方法可以将它变成有效的东西.在这种情况下,我不确定为什么宏会比内联函数更好.这似乎是你真正要求的.

  • 将其转换为有效的一种好方法是使用`({})`GCC扩展.但显然,这只适用于海湾合作委员会.当然,我同意内联函数会更好. (5认同)

MSN*_*MSN 5

如果您确实想这样做,请获取支持C ++ 0x样式lambda的编译器:

#define CStrNullLastNL(str) [](char *blah) {char* nl=strrchr(blah,'\n'); if(nl){*nl=0;} return blah;}(str)
Run Code Online (Sandbox Code Playgroud)

尽管既然CStrNullLastNL基本上是一个函数,您可能应该将其重写为一个函数。


Adi*_*sak 5

可以使用逗号运算符吗?简化示例:

#define SomeMacro(A) ( DoWork(A), Permute(A) )
Run Code Online (Sandbox Code Playgroud)

在这里B = SomeMacro(A)“返回” Permute(A)的结果并将其分配给“ B”。

  • 当然可以,但是不能将控制流语句放入表达式中。那就是棘手的地方。 (3认同)
  • ?:运算符可以很好地用作表达式中的控制流。我用它所有的时间。 (2认同)