scope of struct

S

Szabolcs Borsanyi

Dear all,

I'd like to define a macro that expands to a struct-or-union-specifier.
Inside of this struct there shall be a named structure. Alas, the struct
tag inside the other unnamed structure has the scope of the translation unit,
is that right?
So how could I possibly modify the following simplified code to bring it
back within the language constraints.

#define type_template(typename) \
struct { int a; struct a { struct a *p; typename x; } b; }

int main()
{
type_template(double) A;
type_template(double) B;
type_template(int*) C;
return 0;
}

I have one idea, but that will break if I erase the newline after A;

Thanks,
Szabolcs
 
R

Richard Tobin

Szabolcs Borsanyi said:
I'd like to define a macro that expands to a struct-or-union-specifier.
Inside of this struct there shall be a named structure. Alas, the struct
tag inside the other unnamed structure has the scope of the translation unit,
is that right?

For the declarations inside main(), the scope will be main(), but you
still have the same problem.

The problem is that C doesn't have a "gensym" to create new
names at compile time. Presumably you were thinking of using
__LINE__.

It's a bit less elegant but you could have a two-argument macro that
typedefs a struct, the arguments being the type to base it on and the
name of the new type, and construct a name for the internal struct
out of the new type name using ##.

-- Richard
 
B

Barry Schwarz

Dear all,

I'd like to define a macro that expands to a struct-or-union-specifier.
Inside of this struct there shall be a named structure. Alas, the struct
tag inside the other unnamed structure has the scope of the translation unit,
is that right?
So how could I possibly modify the following simplified code to bring it
back within the language constraints.

#define type_template(typename) \

You could always use
#define type_template(typename, struct_tag) \
struct { int a; struct a { struct a *p; typename x; } b; }

and change this to
struct { int a;
struct struct_tag { struct struct_tag *p;
typename x; } b;
}
int main()
{
type_template(double) A;

and these to
type_template(double, a1) A;
type_template(double) B;

and
type_template(double, a2) B;
etc.
type_template(int*) C;
return 0;
}


Remove del for email
 
H

Hallvard B Furuseth

Szabolcs said:
I'd like to define a macro that expands to a struct-or-union-specifier.
Inside of this struct there shall be a named structure.

You are sure it has to be named? If you need the name e.g. for
offsetof, it usually works to say offsetof(struct <outer>,
Alas, the struct tag inside the other unnamed structure has the scope
of the translation unit, is that right?

Same scope as the outer struct. Though if you switch to C++, the struct
name there is struct said:
(...)
I have one idea, but that will break if I erase the newline after A;

There may be compilers where that also breaks in a macro defining
several such structs separated by backslash-newline. I'm not sure if
it'd be a compiler bug to remove backslash-newline before expanding
__LINE__.
 
B

Barry Schwarz

You are sure it has to be named? If you need the name e.g. for
offsetof, it usually works to say offsetof(struct <outer>,
<outer member>.<inner member>). Though I don't think that's valid C.

Since his internal structure has a pointer to itself, the tag does
seem essential.
Same scope as the outer struct. Though if you switch to C++, the struct


There may be compilers where that also breaks in a macro defining
several such structs separated by backslash-newline. I'm not sure if
it'd be a compiler bug to remove backslash-newline before expanding
__LINE__.


Remove del for email
 
P

Peter Nilsson

Szabolcs Borsanyi said:
... how could I possibly modify the following simplified
code to bring it back within the language constraints.

#define type_template(typename) \
struct { int a; struct a { struct a *p; typename
x; } b; }

int main()
{
type_template(double) A;
type_template(double) B;
type_template(int*) C;
return 0;
}

I have one idea, but that will break if I erase the
newline after A;

#define CAT(a,b) a ## b
#define CAT2(a,b) CAT(a,b)

#define declare_struct_outer(typename) \
struct CAT2(inner_, typename) \
{ \
struct CAT2(inner_, typename) *p; \
typename x; \
}; \
struct CAT2(outer_, typename) \
{ \
int a; \
struct CAT2(inner_, typename) b; \
}

typedef int *int_ptr;

declare_struct_outer(double);
declare_struct_outer(int_ptr);

int main()
{
struct outer_double A;
struct outer_double B;
struct outer_int_ptr C;
return 0;
}
 

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,994
Messages
2,570,223
Members
46,810
Latest member
Kassie0918

Latest Threads

Top