Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function like macros returning a value

Tags:

c

macros

Recently came across following examples which returns a register read __ret but without a return statement

#define READWORD(offset)       ({ \
                 unsigned short __ret=0;\
                 __ret = readw(offset);\
                 __ret; \
                 })

Did Google on the same and found that function like macros can return value. Is it safe to assume that last statement "_ret" is equivalent to returning a value? What if i have another statement after "_ret" which changes __ret value. Which one would get returned?

like image 306
pkumarn Avatar asked Dec 20 '22 05:12

pkumarn


2 Answers

This is using a GCC extension called Statement Expressions.

You can use it unless you need to be portable to compilers other than GCC (and Clang/LLVM).

like image 171
Jonathan Leffler Avatar answered Dec 29 '22 00:12

Jonathan Leffler


Let's break this down. For example, let's see what READWORD(1) will do. The preprocessor will insert this: ( { unsigned short __ret=0; __ret = readw(1); __ret; } )

Now we can see what it's up to. We're just calling a function readw with a parameter (1) and assigning it to an unsigned short. After which we just have the line __ret; Although a perfectly valid statement it doesn't appear it does anything. But read on!

Everything is out of scope after the final }.

But, the enclosing () make all the difference. Elegantly the whole thing is an expression that has the value __ret. So you can assign a varaible to it. This makes the whole thing remarkably stable in macro arguments.

Does this help unpick?

like image 37
Bathsheba Avatar answered Dec 28 '22 22:12

Bathsheba