문제
I have a working hexdump function but it seems to be overkill for printing a single variable. 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
. I think this means that I can't use this method of casting ptr to 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. Note that you may use my macro with an l-value float
and it spits out the correct big-endian representation. 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. In the end I only really just wanted to use it on 32-bit floats.
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).
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.
다른 팁
The error message is saying you cannot take the address of the return value because it is not an L-value. 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.
A function call cannot appear to the left of an assignment--the return value is not an L-value. This is why you get the error. In C, it makes no sense to take the address of the return value. (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.)