J
Juha Nieminen
joe said:Wrong.
Wrong? C++ does not offer tools to abstract the struct hack and make
it easier and safer to use?
We'll have to disagree, then.
joe said:Wrong.
Wrong? C++ does not offer tools to abstract the struct hack and make
it easier and safer to use?
We'll have to disagree, then.
Helge said:Vladimir Jovic said:You switched to interprocess communication. For that, this hack should notHelge said:Helge Kruse wrote:
Well, let's say that the only advantage I can think of with struct
hacks
is efficiency (they consume less memory and are faster to allocate
than
the "normal" solution of allocating the struct and the array
separately).
I can't think of any significant advantages. If memory usage
efficiency
is not an issue, why would I use the struct hack for anything?
Marshalling can be an issue. Think of passing the struct from one
process to another using shared memory. When you have the array in a
stl vector, you have additional costs. The same applies to inter
process communication using any socket layer like TCP.
But in that case, why use hacks of this type? For IPC, you can not pass
pointers. There are other mechanisms, therefore there are no needs for
such hacks.
What pointers? The OP wrote this:
struct SvrList{
unsigned int uNum;
GameSvr svr[0]; //line A
};
be used. For IPC (at least on linux, don't know how it is done on other
platforms), it is done this way:
http://linux.die.net/man/7/mq_overview
http://linux.die.net/man/2/mmap
http://linux.die.net/man/2/shmget
Thanks for these (os-dependent) examples. These functions like msgsnd expect
a pointer to _one_ object. That fits perfect to the struct show above. The
GameSvr array is embedded in the SrvList object. This avoids pointers.
When you have a pointer to an addtional chunk of data, like std::vector
implementations use, instead of an embedded object you have to build an
message object, compose a memory layout and than you are ready to pass it to
msgsend. Finally you drop the temporary object.
gwowen said:The struct hack gives me a storage region of run-time-variable size,
contiguous with a place to store that size itself. Which C++
container gives you that? How would you abstract that requirement.
C++ offers tools for you to build your own abstract containers which
internally use the struct hack, but from the outside are easier and safer
to use than using the raw struct hack directly.
Really? I challenge you write one suitable for use in IPC. Remember,
if your abstract container contains a pointer, its not going to work.
gwowen said:Really? I challenge you write one suitable for use in IPC. Remember,
if your abstract container contains a pointer, its not going to work.
Really? I challenge you write one suitable for use in IPC. Remember,
if your abstract container contains a pointer, its not going to work.
Juha said:"C++ offers you tools" does not mean "C++ offers you a standard
container".
C++ offers tools for you to build your own abstract containers which
internally use the struct hack, but from the outside are easier and
safer to use than using the raw struct hack directly.
Such tools include classes (with public and private sections),
constructors, copy constructors, assignment operator overloading,
destructors, the RAII mechanism, and templates.
In other words, instead of using a raw struct pointer directly (which
points to a memory block which has been "overallocated" for the
purposes
of the struct hack), you use an abstract object which resembles a
smart pointer and which hides and automatizes the low-level dirty
details inside, making the usage of the struct hack easier and safer.
Alf said:* gwowen, on 27.08.2010 13:20:
Please post code that shows the raw struct hack in action without
using a pointer.
joe said:Alf said:* gwowen, on 27.08.2010 13:20:
Please post code that shows the raw struct hack in action without
using a pointer.
struct msg
{
uint32 msg_id;
uint32 data_cap; // capacity
uint32 data_len; // length
char data[1];
msg(uint32 id, uint32 cap, uint32 len, const char* dat)
{
msg_id = id;
data_cap = cap;
data_len = 0;
strncpy(data, dat, len);
}
};
void sendmsg(msg const& m);
const uint32 MSG_ID_HELLO = 1;
int main()
{
unsigned char buff[256];
msg* m =
new((void*)buff) msg(MSG_ID_HELLO, 244, 13, "Hello world!");
sendmsg(m);
return 0;
}
OK. I thought you were saying originally above that C++ offered an
alternative to the struct hack (because you have been on the track that
something with a std::vector in it was the "same thing"). The "same ol"
still applies though: because C++ does not recognize the struct hack as a
viable technique (like C99 does), you're still (and I do, do this)
wrapping a hack that may be compiler-specific or perhaps not guaranteed
to work. And also, it's hackish because in certain forms you loose the
ability to derive from such a wrapper, etc, and is therefore a
dialect-style of C++ programming.
};>::result
Joshua said:I don't think you could ever derive from a struct hack struct in C++.
The data trails off past the end of the struct hack struct, and if you
derive from the struct and add new data members, then those data
members will exist in the "off the end" hack part from the base class.
This makes no sense to me offhand.
Alf said:* gwowen, on 27.08.2010 13:20:
Please post code that shows the raw struct hack in action without
using a pointer.
struct msg
{
uint32 msg_id;
uint32 data_cap; // capacity
uint32 data_len; // length
char data[1];
msg(uint32 id, uint32 cap, uint32 len, const char* dat)
{
msg_id = id;
data_cap = cap;
data_len = 0;
strncpy(data, dat, len);
}
};
void sendmsg(msg const& m);
Ian said:Alf said:* gwowen, on 27.08.2010 13:20:
C++ offers tools for you to build your own abstract containers
which internally use the struct hack, but from the outside are
easier and safer to use than using the raw struct hack directly.
Really? I challenge you write one suitable for use in IPC.
Remember, if your abstract container contains a pointer, its not
going to work.
Please post code that shows the raw struct hack in action without
using a pointer.
struct msg
{
uint32 msg_id;
uint32 data_cap; // capacity
uint32 data_len; // length
char data[1];
msg(uint32 id, uint32 cap, uint32 len, const char* dat)
{
msg_id = id;
data_cap = cap;
data_len = 0;
strncpy(data, dat, len);
}
};
void sendmsg(msg const& m);
The obvious design fix is to pass the header and a pointer to the data
to sendmsg and save the unnecessary copy!
Alf said:* gwowen, on 27.08.2010 13:20:
C++ offers tools for you to build your own abstract containers which
internally use the struct hack, but from the outside are easier and
safer to use than using the raw struct hack directly.
Really? I challenge you write one suitable for use in IPC. Remember,
if your abstract container contains a pointer, its not
going to work.
Please post code that shows the raw struct hack in action without
using a pointer.
struct msg
{
uint32 msg_id;
uint32 data_cap; // capacity
uint32 data_len; // length
char data[1];
msg(uint32 id, uint32 cap, uint32 len, const char* dat)
{
msg_id = id;
data_cap = cap;
data_len = 0;
strncpy(data, dat, len);
}
};
void sendmsg(msg const& m);
The obvious design fix is to pass the header and a pointer to the data to
sendmsg and save the unnecessary copy!
joe said:Alf said:Please post code that shows the raw struct hack in action without
using a pointer.
int main()
{
unsigned char buff[256];
msg* m =
new((void*)buff) msg(MSG_ID_HELLO, 244, 13, "Hello world!");
sendmsg(m);
return 0;
}
joe said:Alf P. Steinbach /Usenet wrote:
Please post code that shows the raw struct hack in action without
using a pointer.
int main()
{
unsigned char buff[256];
msg* m =
new((void*)buff) msg(MSG_ID_HELLO, 244, 13, "Hello world!");
sendmsg(m);
return 0;
}What do you think that 'm' is if not a pointer?And your code perfectly exemplifies why that pointer should be
abstracted
away in C++. You are leaking it.
Sorry, but there is no leak (cannot be as there is no dynamic memory
allocation). And one can easily get rid of the m pointer, it is not
needed here, one could just sendmsg(buff).
OTOH, this code exhibits UB because buff is not guaranteed to be aligned
properly for msg. But this can be fixed.
Alf said:* Ian Collins, on 28.08.2010 01:02:Alf P. Steinbach /Usenet wrote:
* gwowen, on 27.08.2010 13:20:
C++ offers tools for you to build your own abstract containers
which internally use the struct hack, but from the outside are
easier and safer to use than using the raw struct hack directly.
Really? I challenge you write one suitable for use in IPC.
Remember, if your abstract container contains a pointer, its not
going to work.
Please post code that shows the raw struct hack in action without
using a pointer.
struct msg
{
uint32 msg_id;
uint32 data_cap; // capacity
uint32 data_len; // length
char data[1];
msg(uint32 id, uint32 cap, uint32 len, const char* dat)
{
msg_id = id;
data_cap = cap;
data_len = 0;
strncpy(data, dat, len);
}
};
void sendmsg(msg const& m);
The obvious design fix is to pass the header and a pointer to the
data to sendmsg and save the unnecessary copy!
Hm, somehow Joe's reply didn't show up on my server.
So, I don't know what the code above is meant to illustrate (no
context).
However, my question was rhetorical: there's no way to allocate an
arbitrary (known at run time) sized struct without using dynamic
allocation.
Juha said:joe said:Alf said:Please post code that shows the raw struct hack in action without
using a pointer.
int main()
{
unsigned char buff[256];
msg* m =
new((void*)buff) msg(MSG_ID_HELLO, 244, 13, "Hello world!");
sendmsg(m);
return 0;
}
What do you think that 'm' is if not a pointer?
And your code perfectly exemplifies why that pointer should be
abstracted away in C++. You are leaking it.
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.