By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,379 Members | 1,602 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,379 IT Pros & Developers. It's quick & easy.

help: define problem and meaning of {{{ and }}}.

P: n/a
for struct:
struct in6_addr {
uint8_t s6_addr[16];
};

is provided a costant:

#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}}

what does means {{{, and }}}?
why can be used in a declaration only?
thankyou in advance,
MArio.

--------
I refer to:
http://www.faqs.org/rfcs/rfc3493.html
"[...]
The symbolic constant is named IN6ADDR_LOOPBACK_INIT and is
defined in <netinet/in.h>.
It can be used at declaration time ONLY; for example:

struct in6_addr loopbackaddr = IN6ADDR_LOOPBACK_INIT;

Like IN6ADDR_ANY_INIT, this constant cannot be used in an assignment
to a previously declared IPv6 address variable.
[...]
"
May 27 '07 #1
Share this Question
Share on Google+
4 Replies


P: n/a
_mario.lat skrev:
for struct:
struct in6_addr {
uint8_t s6_addr[16];
};

is provided a costant:
this is not a konstant, it is macro _ meaning that it will replate your
initialization in pre-compiler
#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}}
#include <stdio.h>
#include <stdlib.h>

struct in6_addr{
unsigned int s6_addr[16];
};
/*
*you had to may brackets; the firs pair {} is for the struck
*initialization, the second pair {}, inside is for array initialization
*/

#define IN6ADDR_LOOPBACK_INIT {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}

int main(void){

int i;
struct in6_addr a = IN6ADDR_LOOPBACK_INIT ;
/*
*pre-compiler will replace it with {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}
*/

for(i=0;i<16;i++){
printf("%d ", a.s6_addr[i]);
}

return EXIT_SUCCESS;
}
what does means {{{, and }}}?
why can be used in a declaration only?
thankyou in advance,
MArio.

--------
I refer to:
http://www.faqs.org/rfcs/rfc3493.html
"[...]
The symbolic constant is named IN6ADDR_LOOPBACK_INIT and is
defined in <netinet/in.h>.
It can be used at declaration time ONLY; for example:

struct in6_addr loopbackaddr = IN6ADDR_LOOPBACK_INIT;

Like IN6ADDR_ANY_INIT, this constant cannot be used in an assignment
to a previously declared IPv6 address variable.
[...]
"
May 27 '07 #2

P: n/a
"_mario.lat" <no**@libero.itwrites:
for struct:
struct in6_addr {
uint8_t s6_addr[16];
};

is provided a costant:

#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}}

what does means {{{, and }}}?
{{{ is simply a sequence of three distinct { tokens.
Likewise for }}}.
why can be used in a declaration only?
[...]
I refer to:
http://www.faqs.org/rfcs/rfc3493.html
That RFC specifies the IN6ADDR_LOOPBACK_INIT, but it doesn't specify
how it's defined; the triple curly braces don't appear anywhere in the
RFC itself.

Some implementations do use triple braces in their definition of
IN6ADDR_LOOPBACK_INIT. Others don't.

IN6ADDR_LOOPBACK_INIT is intended to expand to an initializer for an
object of type struct in6_addr. If you look at the definition of type
"struct in6_addr", you'll probably see that it consists of an array
within a union within a structure. The definition uses one level of
braces for each level of the type definition.

Note that C is fairly lax about braces in initializers. You can
legally omit some braces; you can even add them in some cases:

int i = { 42 };

But IMHO it's best to have the structure of the initializer match the
structure of the type.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
May 27 '07 #3

P: n/a
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>struct in6_addr {
uint8_t s6_addr[16];
};

is provided a costant:

#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}}

what does means {{{, and }}}?
>IN6ADDR_LOOPBACK_INIT is intended to expand to an initializer for an
object of type struct in6_addr. If you look at the definition of type
"struct in6_addr", you'll probably see that it consists of an array
within a union within a structure.
The OP quoted the definition of struct in6_addr (see above), and it
just consists of an array within the struct. So the mystery is why
there are 3 rather than 2 levels of brace.

Some implementations certainly do define it as a struct containing a
union as you suggested; perhaps the OP has a buggy implementation, or
has misread some #ifdefs or something like that.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
May 27 '07 #4

P: n/a
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>>struct in6_addr {
uint8_t s6_addr[16];
};

is provided a costant:

#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}}

what does means {{{, and }}}?
>>IN6ADDR_LOOPBACK_INIT is intended to expand to an initializer for an
object of type struct in6_addr. If you look at the definition of type
"struct in6_addr", you'll probably see that it consists of an array
within a union within a structure.

The OP quoted the definition of struct in6_addr (see above), and it
just consists of an array within the struct. So the mystery is why
there are 3 rather than 2 levels of brace.

Some implementations certainly do define it as a struct containing a
union as you suggested; perhaps the OP has a buggy implementation, or
has misread some #ifdefs or something like that.
The quoted definition of struct s6_addr is from the RFC. Reading on
in the RFC:

The structure in6_addr above is usually implemented with an embedded
union with extra fields that force the desired alignment level in a
manner similar to BSD implementations of "struct in_addr". Those
additional implementation details are omitted here for simplicity.

An example is as follows:

struct in6_addr {
union {
uint8_t _S6_u8[16];
uint32_t _S6_u32[4];
uint64_t _S6_u64[2];
} _S6_un;
};
#define s6_addr _S6_un._S6_u8

Given such a definition, the triple braces are appropriate (though
single braces would also be legal).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
May 27 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.