On Aug 20, 2:01 am, Andrey Tarasevich <
[email protected]>
wrote:
Pete Becker wrote:
Hi, I need your help.
----------
struct SvrList{
unsigned int uNum;
GameSvr svr[0]; //line A
};
---------
Once I declared a struct like this to store server list info.
It's supposed to be used like this.
----------
SvrList* pList = (SvrList*)malloc(sizeof(
SvrList) + svrNum*sizeof(GameSvr));
pList->uNum, pList->svr[0], pList->svr[1].... blabla..
I wouldn't call this fine. Even
pList->svr[0]
is accessing the element that is out of array's bounds, and
that is UB. How come your program is not crashing, or at
least going crazy? Maybe you are just unlucky to have a bug
hidden.
It's an old C programmers hack. I've come across this idiom in
lot's old C code, particularly driver and os code. Microsoft
Win32 is rife with it.
Except that it's not legal C, either.
Which is why it's referred to above as a "hack". Quite a common one, too.
Usually we use the term "hack" when the code relies on a specific
manifestation of undefined (or unspecified) behavior, but otherwise is
well-formed.
In this case the code is ill-formed, since 0-size array declaration is
illegal in C++ (as well as in C). In other words, arguing about the "out
of bounds" access here doesn't make much sense, since the code is
formally non-compilable.
Wait.. I don't think it's illegal in C++. At least I will definitely
object making it illegal by the standard community.
It can be dangerous but it can also do good. It depends on whether we
are using it correctly.
Will you guys getting crazy if we do things like this
-------code-----
struct A{
int num;
int p[0];};
A *pA = (A*)malloc(sizeof(A)+sizeof(int)*10);
printf("%d\n", &pA->p[10] - &pA->p[0]); //accessing out of
bounds.
------code---
Crazy? Why? C++ compilers should not simply compile it by language
rules that does not allow zero-sized arrays. If a compiler compiles it
then it is non-standard extension.
I have seen similar C code, but that used "int p[1];". If it was
compiled with C++ compiler and run-time bounds-checking on then it did
fault when accessing anything but p[0].
In C++ you should use vector<int> instead, it is about as fast.
I hate vectors, again. C++ is not portable as binary code.
Passing vectors as arguments out of a dll in windows may crash the
system when accessing it.
Assuming binary compatibility without effort is wrong anyway. Are you
seriously claiming that such originally-posted hacks let you to
achieve binary compatibility between modules compiled with different C
compilers and under different compilation options?
nope.. I mean using vectors in module interface may cause
interoperability problems.
My hack can solve the problem in case using the same padding policy
for modules involved.
If same options and same compiler are used then these interoperability
problems you refer to are likely because you add elements to vector or
attempt to destroy it outside of that windows dll context. Your hack
does not even let to add more elements to it (it is like
vector<GameSvr> const) and you may face same problems with C if you
free() it outside of that dll.
Right, but how about passing out the address of the pointer?
The point is adding more elements may make it necessary to move
existing elements elsewhere, so we may need to modify the pointer in
dll.
Actually passing pointers between functions may also cause this kind
of problems, nothing special to communication between DLLs.