简体   繁体   English

十六进制转储宏(C / C ++)

[英]Hexdump macro (C/C++)

I have a working hexdump function but it seems to be overkill for printing a single variable. 我有一个正在运行的hexdump函数,但是对于打印单个变量来说似乎有些矫kill过正。 So I am trying to make a macro for it. 所以我试图为此做一个宏。 So far this works almost perfectly: 到目前为止,这几乎可以正常工作:

#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

The only issue with this is that I cannot use it with the return value of a function. 唯一的问题是我不能将其与函数的返回值一起使用。 I get the error lvalue required as unary '&' operand . 我得到lvalue required as unary '&' operand的错误lvalue required as unary '&' operand I think this means that I can't use this method of casting ptr to uint-ptr. 我认为这意味着我无法使用将ptr转换为uint-ptr的方法。 Is there another efficient way to do this? 还有另一种有效的方法可以做到这一点吗?

Edit : I'd like to mention that what most people glossed over is that I wanted to see my value bit-preserved and converted to an unsigned int hexadecimal format. 编辑 :我想提及的是,大多数人不了解的地方是,我希望看到我的值保留并转换为unsigned int十六进制格式。 Note that you may use my macro with an l-value float and it spits out the correct big-endian representation. 请注意,您可以将我的宏与左值float ,它会吐出正确的big-endian表示形式。 Most regular hex-dump routines will print out the bits as it is written in memory, which clearly is dependent on endianness. 大多数常规的十六进制转储例程都会在将其写入内存时打印出这些位,这显然取决于字节顺序。 My bad for not being clear about what I meant. 我不好意思不清楚我的意思。

Anyway, I ended up writing a set of overloaded functions which can be used with an r-value. 无论如何,我最终写了一组可以与r值一起使用的重载函数。 In the end I only really just wanted to use it on 32-bit floats. 最后,我只是真的只想在32位浮点数上使用它。

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

Macros should be used sparingly because they are highly bug prone, and difficult to debug. 应该谨慎使用宏,因为它们很容易发生错误,并且难以调试。

In this case, you won't get any performance gain from using a macro, because a short function like this is probably going to get inlined. 在这种情况下,使用宏将不会获得任何性能提升,因为这样的短函数可能会被内联。

You will get a readability gain by using a function. 通过使用函数,您将获得更高的可读性。 There are also many language features you get from functions, such as overloading, type safety, and potential to pass it as a function pointer. 您还可以从函数中获得许多语言功能,例如重载,类型安全性以及将其作为函数指针传递的潜力。 You may not need them now, but you might in the future. 您现在可能不需要它们,但将来可能需要。

It will also be easier to write. 它也将更容易编写。

All in all, a function is a much much better choice in this case. 总而言之,在这种情况下,功能是更好的选择。

Plus there are already functions built into the language to do what you're trying to do, both in C++, and in C (if you need the speed). 另外,在C ++和C中(如果需要速度的话),该语言中已经内置了可以完成您想做的功能的函数。

Edit 编辑

If you really want to figure out how to make it a macro, and want to know why this doesn't work, see dappawit's answer. 如果您真的想弄清楚如何使其成为一个宏,并且想知道为什么它不起作用,请参见dappawit的答案。

The error message is saying you cannot take the address of the return value because it is not an L-value. 错误消息表示您不能使用返回值的地址,因为它不是L值。 To take the address, you need an object that actually has an address. 要获取地址,您需要一个实际具有地址的对象。 Such objects can appear on the left size of an assignment, hence the term L-value. 这样的对象可以出现在分配的左侧,因此是术语L值。

A function call cannot appear to the left of an assignment--the return value is not an L-value. 函数调用不能出现在赋值的左侧-返回值不是 L值。 This is why you get the error. 这就是为什么您得到错误。 In C, it makes no sense to take the address of the return value. 在C语言中,获取返回值的地址没有任何意义。 (In C++, you can return references. In that case, you can take the address of the return value. However, other returned values have the same restrictions as in C--they are not L-values.) (在C ++中,您可以返回引用。在这种情况下,您可以获取返回值的地址。但是,其他返回值与C中的限制相同-它们不是L值。)

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

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