Comm in macros

V

valtih1978

I convert ADD_ADDR(@addr, 192,168,3, 1) into

#define IP_NET 192,168,3
ADD_ADDR(@addr, IP_NET, 1)

and get 'ADD_ADDR is undefined'
 
E

Eric Sosman

I convert ADD_ADDR(@addr, 192,168,3, 1) into

#define IP_NET 192,168,3
ADD_ADDR(@addr, IP_NET, 1)

and get 'ADD_ADDR is undefined'

Please post a complete example, including the definition
of ADD_ADDR. From what you've shown, we can only guess at what
you mean by "convert."
 
B

Ben Bacarisse

valtih1978 said:
I convert ADD_ADDR(@addr, 192,168,3, 1) into

#define IP_NET 192,168,3
ADD_ADDR(@addr, IP_NET, 1)

and get 'ADD_ADDR is undefined'

ADD_ADDR is is, presumably, a 5-argument function-like macro. The
invocation that you show has only three arguments and the C
pre-processor won't like that. The error message is a little less than
helpful, because it could have said something more like gcc says:

error: macro "ADD_ADDR" requires 5 arguments, but only 3 given

The problem is that the C pre-processor does not work as you expect.
Macros are not expanded as the arguments are being collected, so IP_NET
stays as one token.

It's not clear what the best fix is. Some idea of what the macros are
meant to achieve would help, but one obvious fix is to provide a
3-argument version of the macro:

#define ADD_ADDR3(addr, net, d) ADD_ADDR(addr, net, d)

It works because macros are expanded when a macro invocation is replaced
by its body.

(By the way, the '@' looks very odd.)
 
P

Phil Carmody

valtih1978 said:
I convert ADD_ADDR(@addr, 192,168,3, 1) into

#define IP_NET 192,168,3
ADD_ADDR(@addr, IP_NET, 1)

I'm happy for you.
and get 'ADD_ADDR is undefined'

I'm sad for you.

Now would you like to ask a sensible question which doesn't
require us to be inside your head to understand?
http://www.catb.org/~esr/faqs/smart-questions.html#bespecific
http://www.catb.org/~esr/faqs/smart-questions.html#beprecise

Due to the precedence of ',', note that
#define IP_NET 192,168,3
is asking for an enormous number of nasty unwanted things to
happen. Avoid making the right hand side of a macro definition
anything which could be split into multiple parts or in different
ways depending on context.

Phil
--
What Alice Hill, President at Slashdot Media, writes:
Proven track record innovating and improving iconic websites
(Slashdot.org, ...) while protecting their voice and brand integrity
What Alice Hill means:
2013: Completely fucked up Slashdot, and ignored almost endless
negative feedback about her unwanted changes. 2014: Killed slashdot.
 
K

Kaz Kylheku

I convert ADD_ADDR(@addr, 192,168,3, 1) into

#define IP_NET 192,168,3
ADD_ADDR(@addr, IP_NET, 1)

and get 'ADD_ADDR is undefined'

Are you sure? Perhaps your compiler says that ADD_ADDR cannot be
called with three arguments?

IP_NET is a single macro argument. It is identified as the second
argument of the macro call, and only then does expansion take
which produces the commas.

To fix this you have to make a three-argument ADD_ADDR.

Consider this example:

#define abc(A, B, C) f(A, B, C)
#define xy(X, Y) abc(X, Y)
#define two3 2, 3
xy(1, two3)

Expansion with gcc's preprocessor, from the shell:

$ gcc -E macro.c
# 1 "macro.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "macro.c"



f(1, 2, 3)


(That doesn't prove it's standard or correct, of course; it's just
a confidence-improving test case.)

As you can see, the xy(X, Y) macro serves as a two-argument interface
to the abc macro. Y is expected to be some item that expands to
a two-element comma separated list.
 
J

Jorgen Grahn

I convert ADD_ADDR(@addr, 192,168,3, 1) into

#define IP_NET 192,168,3
ADD_ADDR(@addr, IP_NET, 1)

and get 'ADD_ADDR is undefined'

I don't see why you have to do it this way (although you don't explain
what you're trying to do).

With IP/IPv6 addresses, I find (for my use cases) that it's better to:

- keep them as strings for as long as possible, if that's
what they start out as
- use getaddrinfo()[1] if you need to use them to create sockets
etc; that one too takes strings
- when that's no longer feasible, switch over to struct in_addr or
struct in6_addr using inet_ntop/inet_pton.

I also get the impression you are about 20 years behind. We have
classless routing now, and A, B and C networks have gone the way of
the dodo. 192.168.3.x is now[2] 192.168.0/24, and you also have to
consider 192.168.0/25, 192.168.0/26, 192.168.128/25 in the general
case ...

/Jorgen

[1] Or whatever your environment supplies. I'm assuming POSIX, but
surely Windows has something equivalent.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top