471,310 Members | 1,110 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,310 software developers and data experts.

Initialize pointer-to-struct declaration to an unnamed struct?

Is it possible to have a declaration of a struct pointer initialized
to an unnamed struct?
(I'm only concerned with static/global variables, if it matters.)

I'm trying to do something like:

struct st_a {
int i, j;
};

struct st_b {
int k, l;
st_a *m;
} b[] = {
1, 2, {0, 1},
3, 4, {0, 2}
};

It could be done by declaring each "sub-struct" with a name, then
pointing to these,
but besides being more work it's also more difficult to read when the
idea is a hierarchy.

Jun 26 '07 #1
18 8741
Ehud Shapira wrote:
Is it possible to have a declaration of a struct pointer initialized
to an unnamed struct?
(I'm only concerned with static/global variables, if it matters.)

I'm trying to do something like:

struct st_a {
int i, j;
};

struct st_b {
int k, l;
st_a *m;
} b[] = {
1, 2, {0, 1},
3, 4, {0, 2}
{0, 1} is not a valid initializer for a pointer.
};

It could be done by declaring each "sub-struct" with a name, then
pointing to these,
but besides being more work it's also more difficult to read when the
idea is a hierarchy.
It's not quite clear to me what you actually want.

Jun 26 '07 #2
{0, 1} is not a valid initializer for a pointer.
I know. What *can* be valid? You can see what sort of initialization
I'm trying to do.

Jun 26 '07 #3
Ehud Shapira wrote:
>{0, 1} is not a valid initializer for a pointer.
I know. What *can* be valid? You can see what sort of initialization
I'm trying to do.
Actually, I can't. Why does it have to be a pointer? Can't you just store a
struct directly?

Jun 26 '07 #4
On Jun 26, 11:17 pm, Rolf Magnus <ramag...@t-online.dewrote:
Actually, I can't. Why does it have to be a pointer? Can't you just store a
struct directly?
What I want to do involves a hierarchy of variable length struct
arrays. But regardless of the why, the question is whether it's
possible at all to do something like ( char *pc = "something" ) for a
struct and not char.

Jun 26 '07 #5
Ehud Shapira wrote:
On Jun 26, 11:17 pm, Rolf Magnus <ramag...@t-online.dewrote:
>Actually, I can't. Why does it have to be a pointer? Can't you just
store a struct directly?
What I want to do involves a hierarchy of variable length struct
arrays. But regardless of the why, the question is whether it's
possible at all to do something like ( char *pc = "something" ) for a
struct and not char.
Usually not. There is a huge difference between a string literal (that
has a very very very long lifetime) and a struct temporary. You could
create a static object of the struct type, and then declare a pointer
and initialise it with the address of the static object:

static somestruct something = { blah };
somestruct *ps = &something;

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 26 '07 #6
>There is a huge difference between a string literal and a struct temporary.
The struct is just as static -- it's a global definition.
You could create a static object of the struct type, and then declare a pointer
and initialise it with the address of the static object:
That's what I'm trying to avoid; naming every linked array of structs.

Jun 26 '07 #7
Ehud Shapira wrote:
>There is a huge difference between a string literal and a struct
temporary.
The struct is just as static -- it's a global definition.
No, a temporary created for the purposes of initialising something is
definitely not static. It's temporary.
>You could create a static object of the struct type, and then
declare a pointer and initialise it with the address of the static
object:
That's what I'm trying to avoid; naming every linked array of structs.
<shrug Don't name them. Have an array and get pointers to its
elements:

struct st_a {
int i, j;
} a[] = { { 0, 1 }, {0, 2 } };

struct st_b {
int k, l;
st_a *m;
} b[] = {
{ 1, 2, a+0 },
{ 3, 4, a+1 }
};

You won't have "every" element named, only one.

Another solution is to create those dynamically:

struct st_a {
int i, j;
};

st_a* make_st_a(int i, j) {
st_a a = {i, j};
return new st_a(a);
}

struct st_b {
int k, l;
st_a *m;
} b[] = {
1, 2, make_st_a(0, 1),
3, 4, make_st_a(0, 2)
};

If 'b' is static, you don't have to care about disposing of
those dynamic objects, a small leak like that isn't going to
hurt much. Just be aware of it.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '07 #8
On Jun 26, 8:52 pm, Ehud Shapira <ehudshap...@hotmail.comwrote:
Is it possible to have a declaration of a struct pointer initialized
to an unnamed struct?
(I'm only concerned with static/global variables, if it matters.)
I'm trying to do something like:
struct st_a {
int i, j;
};
struct st_b {
int k, l;
st_a *m;} b[] = {
1, 2, {0, 1},
3, 4, {0, 2}
};
It can't be done in C++. In C you can write something like:

typedef struct
{
int i, j ;
} st_a ;

typedef struct
{
int k, l ;
st_a* m ;
} st_b ;

st_b b[] = {
{ 1, 2, &(st_a){ 0, 1 }, },
{ 3, 4, &(st_a){ 0, 2 }, },
} ;

but this was added to C after C++ was standardized. (Possibly
some C++ compilers support it anyway. I don't know.)
It could be done by declaring each "sub-struct" with a name, then
pointing to these,
but besides being more work it's also more difficult to read when the
idea is a hierarchy.
In such cases, I usually define the data in a simple text file,
and then write a small program to convert it into legal C++.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '07 #9
On Jun 27, 2:33 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>The struct is just as static -- it's a global definition.
No, a temporary created for the purposes of initialising something is
definitely not static. It's temporary.
I don't understand that. Maybe we are talking about different things?
The struct will be initialized at compile-time, and so will live
"forever". How is that temporary?
<shrug Don't name them. Have an array and get pointers to its
elements:
Bookkeeping array indexes isn't much better. And dynamically creating
them would add overhead, etc.

On Jun 27, 12:03 pm, James Kanze <james.ka...@gmail.comwrote:
In such cases, I usually define the data in a simple text file,
and then write a small program to convert it into legal C++.
Yeah, if that's the case, for big definitions I'll probably go with a
custom preprocessor, possibly outputting binary directly (which would
also rid me of unclear handling of union initialization by VC6... but
maybe that's the problem; using an old compiler.)

Too bad C/++ doesn't offer (in many cases) such terseness as that
possible by, say, JavaScript.

Thanks all for the feedback.

Jun 27 '07 #10
eh*********@gmail.com wrote:
On Jun 27, 2:33 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>>The struct is just as static -- it's a global definition.
No, a temporary created for the purposes of initialising something is
definitely not static. It's temporary.

I don't understand that. Maybe we are talking about different things?
The struct will be initialized at compile-time, and so will live
"forever". How is that temporary?
In the statement

T obj = someexpression;

(provided it appears at the namespace scope) 'obj' has static storage
duration, but whatever 'someexpression' returns does NOT have static
storage duration, it's a temporary. That's significantly different
from

char const* p = "blah";

where the string literal ("blah") has static storage duration.
>
><shrug Don't name them. Have an array and get pointers to its
elements:

Bookkeeping array indexes isn't much better. And dynamically creating
them would add overhead, etc.

On Jun 27, 12:03 pm, James Kanze <james.ka...@gmail.comwrote:
>In such cases, I usually define the data in a simple text file,
and then write a small program to convert it into legal C++.

Yeah, if that's the case, for big definitions I'll probably go with a
custom preprocessor, possibly outputting binary directly (which would
also rid me of unclear handling of union initialization by VC6... but
maybe that's the problem; using an old compiler.)

Too bad C/++ doesn't offer (in many cases) such terseness as that
possible by, say, JavaScript.
Huh? Terseness?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '07 #11
On Jun 27, 5:23 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
T obj = someexpression;

(provided it appears at the namespace scope) 'obj' has static storage
duration, but whatever 'someexpression' returns does NOT have static
storage duration, it's a temporary.
If (someexpression) is (a + b) then I can see how it's temporary, but
what's temporary about a struct defined at compile-time? Just like a
string, it would have a memory address and content defined before any
instruction is executed.
Huh? Terseness?
Stuff like:

b = [
{ k:1, l:2, m:[ { i:0, j:1 } ] }
];

Jun 27 '07 #12
Ehud Shapira wrote:
On Jun 27, 5:23 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
> T obj = someexpression;

(provided it appears at the namespace scope) 'obj' has static storage
duration, but whatever 'someexpression' returns does NOT have static
storage duration, it's a temporary.
If (someexpression) is (a + b) then I can see how it's temporary, but
what's temporary about a struct defined at compile-time? Just like a
string, it would have a memory address and content defined before any
instruction is executed.
There is no such concept in C++ as "struct defined at compile time".
Taking an address requires an l-value. To define an l-value, you need
to define a *named* object or an element/subobject of an array/another
object.
>Huh? Terseness?
Stuff like:

b = [
{ k:1, l:2, m:[ { i:0, j:1 } ] }
];
How does that relate to your problem? You're trying to initialise
a pointer with an address of a temporary.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '07 #13
Ehud Shapira wrote:
On Jun 27, 5:23 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
> T obj = someexpression;

(provided it appears at the namespace scope) 'obj' has static storage
duration, but whatever 'someexpression' returns does NOT have static
storage duration, it's a temporary.
If (someexpression) is (a + b) then I can see how it's temporary, but
what's temporary about a struct defined at compile-time?
The C++ standard says that it is one.
Just like a string, it would have a memory address and content defined
before any instruction is executed.
When will the destructor be executed?

Jun 28 '07 #14
On Jun 27, 5:19 pm, ehudshap...@gmail.com wrote:
On Jun 27, 2:33 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
The struct is just as static -- it's a global definition.
No, a temporary created for the purposes of initialising something is
definitely not static. It's temporary.
I don't understand that. Maybe we are talking about different things?
The struct will be initialized at compile-time, and so will live
"forever". How is that temporary?
At present, an object created as part of an initialization
expression is a temporary, it's destructor is called and the
memory it allocates is freed as soon as the initialization is
finished. Thus, for example, you could get the code to pass the
compiler by declaring constructors for the referred to struct's,
and defining an operator&() in them which returned the this
pointer. All you'd end up with, however, is dangling pointers.

Of course, if C++ added some special syntax to support such
things, a la C, then the lifetime of the objects would be
whatever C++ decided for those types of objects---in C, they
have static lifetime. (But C isn't C++, and such compound
initializers for a static object must have static initialization
themselves.)
<shrug Don't name them. Have an array and get pointers to its
elements:
Bookkeeping array indexes isn't much better. And dynamically creating
them would add overhead, etc.
On Jun 27, 12:03 pm, James Kanze <james.ka...@gmail.comwrote:
In such cases, I usually define the data in a simple text file,
and then write a small program to convert it into legal C++.
Yeah, if that's the case, for big definitions I'll probably go with a
custom preprocessor, possibly outputting binary directly (which would
also rid me of unclear handling of union initialization by VC6... but
maybe that's the problem; using an old compiler.)
I'm not sure what the problem is in VC++, but C++ doesn't have
designaged initializers either, and so you can only initialize
the first element of a union.
Too bad C/++ doesn't offer (in many cases) such terseness as that
possible by, say, JavaScript.
The languages are designed to meet different goals. I'd
certainly not want to develop anything really large in
JavaScript. A bit of redundancy is necessary when trying to get
different people, or even just separately compiled modules, to
work together.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 28 '07 #15
On Jun 28, 1:05 pm, James Kanze <james.ka...@gmail.comwrote:
At present, an object created as part of an initialization
expression is a temporary, it's destructor is called and the
memory it allocates is freed as soon as the initialization is
finished.
Thanks for clearing that up a bit. So the scope of the object/
sub-struct would be the initialization block, and since that
doesn't make sense, anonymous recursive objects aren't allowed?

How's that behavior useful for anything? I'd expect the scope
to be that of the containing parent.
I'm not sure what the problem is in VC++, but C++ doesn't have
designaged initializers either, and so you can only initialize
the first element of a union.
Yes, it expects the type of the first union member. (Which I
find an unclear limitation; the whole idea of a union is to
hold any of its types. [I also see the {.union_member = 1}
syntax unnecessarily verbal]).

But what's odd is that the first array element does accept a
non-first type, and only later array elements result in
compiler complaints.
The languages are designed to meet different goals. I'd
certainly not want to develop anything really large in
JavaScript.
I'm not suggesting to use JS for "real" programming, but some
syntax possiblities are nice, and I think could work in C++
without conflicting with its syntax.

I guess C++ does pick up some things from here and there (like
C), and has quite possibly improved already; maybe I'm just not
seeing it w/ VC6.

Victor Bazarov:
>How does that relate to your problem? You're trying to
initialise a pointer with an address of a temporary.
No. I was trying to initialize a hierarchial piece of data
in a concise and clean way.

Rolf Magnus:
>Just like a string, it would have a memory address and content defined
before any instruction is executed.
When will the destructor be executed?
The scope of the parent initialization is global, so I didn't
expect any freeing to be necessary.

Jun 28 '07 #16
On Jun 28, 1:05 pm, James Kanze <james.ka...@gmail.comwrote:
At present, an object created as part of an initialization
expression is a temporary, it's destructor is called and the
memory it allocates is freed as soon as the initialization is
finished.
Thanks for clearing that up a bit. So the scope of the object/
sub-struct would be the initialization block, and since that
doesn't make sense, anonymous recursive objects aren't allowed?

How's that behavior useful for anything? I'd expect the scope
to be that of the containing parent.
I'm not sure what the problem is in VC++, but C++ doesn't have
designaged initializers either, and so you can only initialize
the first element of a union.
Yes, it expects the type of the first union member. (Which I
find an unclear limitation; the whole idea of a union is to
hold any of its types. [I also see the {.union_member = 1}
syntax unnecessarily verbal]).

But what's odd is that the first array element does accept a
non-first type, and only later array elements result in
compiler complaints.
The languages are designed to meet different goals. I'd
certainly not want to develop anything really large in
JavaScript.
I'm not suggesting to use JS for "real" programming, but some
syntax possiblities are nice, and I think could work in C++
without conflicting with its syntax.

I guess C++ does pick up some things from here and there (like
C), and has quite possibly improved already; maybe I'm just not
seeing it w/ VC6.

Victor Bazarov:
>How does that relate to your problem? You're trying to
initialise a pointer with an address of a temporary.
No, I was after initializing a hierarchial piece of data
concisely and cleanly.

Rolf Magnus:
>Just like a string, it would have a memory address and content
defined before any instruction is executed.
When will the destructor be executed?
The scope of the parent initialization is global, so I didn't
expect any freeing to be necessary.

Jun 28 '07 #17
On Jun 29, 12:11 pm, James Kanze <james.ka...@gmail.comwrote:
>So the scope of the object/sub-struct would be the initialization
block, and since that doesn't make sense, anonymous recursive
objects aren't allowed?
I don't think that's the issue. If I write something at
namespace scope like:

std::string s( str1 + str2 ) ;
But here there's a ctor (and computation), so a temporary would make
sense. My deceleration had neither.
The problem is that we're discussing something that
isn't currently present in C++,
That's what I now understand. What I used was initializing multiple
flat arrays and linkings them by their names. I don't want dynamic
initialization; I'd rather have static data static.
>Yes, it expects the type of the first union member. (Which I
find an unclear limitation; the whole idea of a union is to
hold any of its types. [I also see the {.union_member = 1}
syntax unnecessarily verbal]).
So how else would you choose...
What other syntax would you suggest?
The most logical thing would be to accept any type the union can hold.
If it's both an int and float, I shouldn't have to cast either.

As for .member, it seems I was mistaken. Naming members on
initialization isn't required, it's just another option. (Looks like
it might also be allowed to initialize a single object with a mix of
named and unnamed, for easy skipping of members, which is nice. But I
can't check all that on my compiler).
>But what's odd is that the first array element does accept a
non-first type, and only later array elements result in
compiler complaints.
You've confused me here. Could you give an example.
Actually, I misinterpreted the reason why an initializer of a union
(which is part of an array) worked even though its type was not the
same as the first union member. It wasn't about being the first in
array, it seems. The compiler somehow accepts offsetof(st, m) as a
pointer when m is the first member of st.
Using new in C++ gives dynamic initialization and dynamic
lifetime. If the objects have a POD type, you never delete
them, and they are created during initialization of static
objects, their effective lifetime is the same as if they were
static. But the initialization remains dynamic;
Do you mean ones declared without "new"? If they're practically
static, why would they have to be created dynamically?

Checking the compiled code of a simple test, it seems a global
initialized struct is really static; it has a static address (no
indirection) and the data is preinitialized.

Jun 29 '07 #18
But that doesn't help choose which element is being initialized.
union U
{
double d1 ;
double d2 ;
} u = 3.1415 ;
Both are the same, there's no "which".
union U
{
long l ;
double d ;
} u = 42 ;

Which element is being initialized?
Here there's ambiguity, so in this case I agree further qualification
would be needed. But requiring it for simple cases seems redundant.
int* p = new int ;
Of course this would be dynamic (with perhaps being optimized to a
static when this makes sense). I thought you were talking about cases
like simple, ctor-less, initialized structs.

Jun 30 '07 #19

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Mario S. | last post: by
4 posts views Thread by Avner Flesch | last post: by
3 posts views Thread by Tony Johansson | last post: by
20 posts views Thread by __PPS__ | last post: by
reply views Thread by Bruno Rodrigues | last post: by
reply views Thread by Bryan | last post: by
8 posts views Thread by bryan | last post: by
12 posts views Thread by NewToCPP | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.