Unidentified Macro C

I came across a macro defined in the C header file, which I am a little versed in.

#if BAR #define FOO(s,err) \ ((SOMEPOINTER)(s))->VALID != SOMEVARIABLE \ ? (err) \ : #else #define FOO(s,err) 

and what is he. I understand what happens with if / else , but I'm not sure what the first definition of the FOO macro does. There, obviously, a triple operation takes place, but I wonder how -> , since I can not find links to it on the Internet. I'm also curious that there are no return values ​​here. What is the point of comparing if you are not returning anything, regardless of the result? Honestly, the guys beat me there too.

+6
source share
3 answers

To answer your inquiries,

  • -> is the structure pointer dereference operator used to refer to a member variable of a pointer to a structure type.

  • \ used to record multi-line MACROS. With respect to standard C11 , chapter §6.10.3,

Parameters are indicated by an optional list of identifiers, the scope of which extends from their declaration in the list of identifiers to a newline that ends the preprocessor #define directive.

So, to cover the MACRO definition over several lines, you need to use \ .

  1. #define MACROs do not return any value. It was considered as a text replacement at the pre-processing stage.
+7
source
 if the name 'BAR' is defined to the pre processor of the compiler then define a macro 'FOO( s, err )' with the replacement text: "((SOMEPOINTER)(s))->VALID != SOMEVARIABLE ? (err) :" which is a ternary operator with a missing final parameter (so it would use what ever statement follows the macro invocation else, when the name 'BAR' is not known to the pre processor of the compiler then define the macro 'FOO( s, err )' as 'nothing (so what ever statement follows the macro invocation will always be executed, rather than conditionally executed (as it would be above) 
+4
source

To answer your question about ternary , this is either an example of an error (forgetting to finish entering the code), or someone is trying to create their own (strange and contradictory) syntax. A macro can be used as follows:

 FOO(someVar, doThisIfSomeVarIsBad) doThisIfSomeVarIsGood(stuff); 

Where someVar is a pointer (pointer to struct or pointer to structure converted to another type of pointer), doThisIfSomeVarIsBad is a pointer to the error display function, and doThisIfSomeVarIsGood(stuff) is any statement.

This is pretty general (as your example), but I hope you get this idea.

This is a funny, but still weird way of handling errors. But well, this is not so bad, I have seen worse abuse of the preprocessor ...

To answer your other questions :

((SOMEPOINTER)(s))->VALID means that you send s to the type of the pointer to the structure and get access to its member ( -> means access to the struct element through a pointer to the structure).

\ , appearing before a new line, "escapes" a new line. This is necessary because #define -s must be (formally) single-line, so if you split the macro between lines, you must make the compiler think that it is still one.

And yes, functional macros are different from built-in functions; they do not return anything. These are simple tools for replacing text; they simply replace some code with some other code.

+2
source

Source: https://habr.com/ru/post/987693/


All Articles