【问题标题】:Hexdump macro (C/C++)十六进制转储宏 (C/C++)
【发布时间】:2011-03-19 04:07:20
【问题描述】:

我有一个可用的 hexdump 函数,但打印单个变量似乎有点过头了。所以我正在尝试为它制作一个宏。到目前为止,这几乎可以完美运行:

#define PRINT_FMT2(val,des,fmt) printf(#des" = "fmt": "SRC_STRN,val)
// SRC_STRN is a macro that evals to string literal containing file and line# 

#include <stdint.h>
#define PRINT_HEX(x) PRINT_FMT2((*((uint32_t*)(&(x)))),x,"%x") 
// the lack of parens around 2nd arg to PRINT_FMT2 is okay cause it gets #'d

唯一的问题是我不能将它与函数的返回值一起使用。我收到错误lvalue required as unary '&amp;' operand。我认为这意味着我不能使用这种将 ptr 转换为 uint-ptr 的方法。还有其他有效的方法吗?

编辑:我想提一下,大多数人掩盖的是我希望看到我的值被保留并转换为无符号整数十六进制格式。请注意,您可以将我的宏与左值 float 一起使用,它会吐出正确的大端表示。大多数常规的十六进制转储例程将在写入内存时打印出这些位,这显然取决于字节序。我不清楚我的意思是什么。

无论如何,我最终编写了一组可与 r 值一起使用的重载函数。最后,我真的只是想在 32 位浮点数上使用它。

inline uint32_t tohex(float f) { 
  uint32_t* u = (uint32_t *)&f; return *u; 
}

【问题讨论】:

  • 不要这样做。函数是比宏更好的选择。它不会为您购买任何东西来使用宏以及滥用宏的设计用途(它不是功能替换)。
  • 函数的有效方法。你在浪费时间并且不必要地使你的代码复杂化。
  • 您可以通过在宏中声明一个用于保存x 值的变量来使其工作,但仅使用函数可能更好。
  • 不要这样做,你只是无缘无故地让你的代码复杂化。
  • 没有理由在你的函数中使用fcpy。取f的地址即可。

标签: c++ c macros hexdump


【解决方案1】:

应谨慎使用宏,因为它们极易出现错误且难以调试。

在这种情况下,您不会从使用宏中获得任何性能提升,因为像这样的短函数可能会被内联。

您将通过使用函数获得可读性增益。您还可以从函数中获得许多语言特性,例如重载、类型安全以及将其作为函数指针传递的可能性。您现在可能不需要它们,但将来可能需要。

也会更容易写。

总而言之,在这种情况下,函数是更好的选择。

此外,在 C++ 和 C 语言中(如果您需要速度的话),语言中已经内置了一些函数来完成您想做的事情。

编辑

如果您真的想弄清楚如何使其成为宏,并且想知道为什么这不起作用,请参阅 dappawit 的答案。

【讨论】:

    【解决方案2】:

    错误消息是说您不能获取返回值的地址,因为它不是 L 值。要获取地址,您需要一个实际具有地址的对象。这样的对象可以出现在赋值的左侧,因此称为 L 值。

    函数调用不能出现在赋值的左侧——返回值不是左值。这就是您收到错误的原因。在 C 中,获取返回值的地址是没有意义的。 (在 C++ 中,您可以返回引用。在这种情况下,您可以获取返回值的地址。但是,其他返回值具有与 C 中相同的限制——它们不是 L 值.)

    【讨论】:

    • 我已经了解了所有这些,但是您再次阅读它真的很棒,我相信它会对这个问题的未来读者有所帮助。 +1。如果没有人很快发布“不要为此使用宏!”的答案。我会接受的。
    • 我很感激。但是,除非你认为这是正确的答案,否则不要接受它。在我看来,偶尔不接受任何答案是完全可以的。
    • 并且记录在案,其他评论者在我看来是正确的——这不是宏的好用处。
    猜你喜欢
    • 2018-11-18
    • 2011-08-02
    • 2022-12-20
    • 1970-01-01
    • 2017-07-31
    • 2013-07-20
    • 2012-06-17
    • 2010-10-04
    • 1970-01-01
    相关资源
    最近更新 更多