MACRO question

Hi guys.
I have question regarding macro:

1
2
3
#define          tcp_sndbuf(pcb)          (TCPWND16((pcb)->snd_buf))

 #define TCPWND16(x)             (x) 


What do they mean? is it function inside macro?
Last edited on
gcc -E is your friend.
It just runs the pre-processor step, so all #includes and #defines are fully processed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ cat bar.c
#define tcp_sndbuf(pcb)          (TCPWND16((pcb)->snd_buf))
#define TCPWND16(x)             (x) 

int main()
{
    int foo;
    tcp_sndbuf(foo);
    return 0;
}

$ gcc -E bar.c
# 1 "bar.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "bar.c"



int main()
{
    int foo;
    (((foo)->snd_buf));
    return 0;
}


All TCPWND16 does is put parentheses around the macro parameter.
All tcp_sndbuf does is append ->snd_buf to the now parenthesised parameter, then put parentheses around the whole lot.
macros can be functions.
here, it says that tcp_sndbuf is the 'function', with a parameter called pcb.
the other one does not do anything and is probably a hack to make something that no longer exists work in old code(?).

Macros are best avoided unless there is no other way; you have lost type safety (what is the type of pcb?) and get weird errors (try tcp_sndbuf("fubar") and look at the confusing error message) and they are prone to creating bugs and causing problems. There really is no reason not to do this some other way.
That is the advantage and disadvantage of using macros. You can do virtually anything programmatic using a macro. Since macros are mere text replacement by the preprocessor they aren't type safe and can end up making maintenance a PITA.

https://stackoverflow.com/questions/1351051/problem-with-macros

The C++ stdlib has lambdas that help correct many of the issues with macros.

https://en.cppreference.com/w/cpp/language/lambda
so in tcp_sndbuf(pcb), pcb argument needs to be a pointer to struct
(unless what is the point of pointing to attribute: (pcb)->snd_buf)?
> so in tcp_sndbuf(pcb), pcb argument needs to be a pointer to struct
Yes it does.

After all the substitution, the result still needs to make sense in the context that it's used in.

OK i get it. I hope you can help me with yet another unclear DEFINE phrase:

/**
* members common to struct tcp_pcb and struct tcp_listen_pcb
*/

1
2
3
4
5
6
7
8
9
10

#define TCP_PCB_COMMON(type) \
  type *next; /* for the linked list */ \
  void *callback_arg; \
  TCP_PCB_EXTARGS \
  enum tcp_state state; /* TCP state */ \
  u8_t prio; \
  /* ports are in host byte order */ \
  u16_t local_port


specifically, i didn't understand backslash use
How is this DEFINE is structured? why it is uses ; ?
\ just means line continuation when used as the last char on a line.

A #define needs to be on one line so to split it across multiple lines for ease of reading \ is used as a line continuation so that effectively as far as the preprocessor is concerned this is all just one line.
I see, ok, so why DEFINE line is so long and contain ;?

we have a macro: MACRO TCP_PCB_COMMON(type)

What is the definition of that?



so why DEFINE line is so long and contain ;

The DEFINE contains 5 statements and comments.
That makes it lengthy;
The author of the macro decided that the 5 lines occurred together often enough that they should be substituted by a single line or that it was important that the 5 lines always occur together.

Note that line 5 appears to be another macro which is expanded in place.
We can't know the full expansion without knowing the expansion of TCP_PCB_EXTARGS.
What is the definition of that?

The definition of the macro is exactly what is shown.
Note that the argument type is used on line 3.
Note that line 9 does not have a ; therefore one is needed after invoking the macro;

As Salem C suggested above, your compiler option to display macro expansions is your friend. The option will show you exactly what the preprocessor sees.
Last edited on
Thanks :)
Topic archived. No new replies allowed.