I recently found this GCC macro:
#define max(a,b) \
({ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; })
I didn't realize before I saw this code, that a block of code {...}
can somehow return value in C.
1) Could you give me a hint how this works?
Though, I usually was able to achieve the same result by abusing the comma operator:
#define max(a,b) \
(typeof (a) _a = (a), \
typeof (b) _b = (b), \
(_a > _b ? _a : _b))
or if it was only for side-effect I would use do { ... } while(0)
2) What is the preferred way of doing this?
A return is a value that a function returns to the calling script or function when it completes its task. A return value can be any one of the four variable types: handle, integer, object, or string. The type of value your function returns depends largely on the task it performs.
JavaScript passes a value from a function back to the code that called it by using the return statement. The value to be returned is specified in the return. That value can be a constant value, a variable, or a calculation where the result of the calculation is returned.
A Python function will always have a return value. There is no notion of procedure or routine in Python. So, if you don't explicitly use a return value in a return statement, or if you totally omit the return statement, then Python will implicitly return a default value for you.
Within the body of the method, you use the return statement to return the value. Any method declared void doesn't return a value. It does not need to contain a return statement, but it may do so.
It is a GCC extension. The comma operator doesn't work:
// C89, doesn't work...
#define max(a,b) \
(typeof (a) _a = (a), \
typeof (b) _b = (b), \
(_a > _b ? _a : _b))
The comma operator only works with expressions, and typeof(a) _a = (a);
is a declaration, not an expression. It is not really possible to write an equivalent macro without either GCC extensions or C11, which has _Generic
. Note that typeof
is als a GCC extension, so you don't gain any portability by eliminating ({...})
unless you eliminate typeof
too.
Here is a C11 version, note how verbose it is by comparison (and it only handles two types!). C11 isn't even supported yet, good luck trying to find a compiler to test this:
// C11
static inline int maxi(int x, int y) { return x > y ? x : y; }
static inline long maxl(long x, long y) { return x > y ? x : y; }
#define max(x, y) _Generic((x), \
long: maxl(x,y), \
int:_Generic((y), \
int: maxi(x,y), \
long: maxl(x,y)))
In portable C99, you can write a macro or inline function that achieves the same effect, except it will only work for one type per macro.
// C99
static inline int maxi(int x, int y) { return x > y ? x : y; }
In C89/C90, I can't think of any way to write the macro in such a way that it won't evaluate x
or y
twice.
The ({ ... })
construct is a gcc extension.
So is the typeof
operator.
A MAX
macro (note the conventional use of all-caps) is easy enough to write:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
It does evaluate one of its arguments more than once, so you shouldn't invoke it as, for example, MAX(x++, y--)
. The use of all-caps serves to remind the user that it's a macro, not a function, and to be careful about arguments with side effects.
Or you can write a function (perhaps an inline one) for each type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With