Re: creating a pointer to a imbeded struct causes C2065



The whole sequence of code below is so deeply suspect, that I'm surprised the compiler
didn't reject it just for being bogus.

See below...
On Wed, 28 Nov 2007 15:06:02 -0800, amccombs <amccombs@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:

I want to create a pointer of a sub struct because there will be more than
one of them in a message. However I get C2065 error. I found the error
explaination on Microsoft.com however I don't see how it applies to me. Here
is a simple idea of what I am doing.


char szBuffer[100];
****
What is the purpose of a 'char' array of fixed size? There are problems with the use of
'char', which should be reserved for very rare and exotic situations. It is not clear you
have an instance of this, without knowing more context. But I tend to get nervous when I
see char and char arrays. Maybe you are reading a sequence of bytes, in which case, you
should declare the array of type BYTE.
*****

typedef struct T_Smoo
****
There is no need for T_Smoo, so drop the tag. It is just clutter
****
{
struct
****
But here, where you needed a tag, you didn't use one!
****
{
int a;
}H;
struct
****
Ditto. struct DType (see comments below)
****
{
int b;
int c;
int d;
}D;
} Smoo;

Smoo *pSmoo = (Smoo*) szBuffer;
****
This is usually a mistake. First, you have not given enough context to explain why this
makes sense. You have no idea if 100 is too big or too small for a message. Declaring
BYTE arrays as char is confusing, because char is signed, but if what you have is a byte
sequence, DECLARE it as a BYTE sequence, not a char sequence.
****
pSmoo->H.a = 1;
pSmoo->D.b = 2;
pSmoo->D.c = 3;
pSmoo->D.d = 4;
int offset = sizeof(pSmoo->H);
Smoo::D *p = (&Smoo::D) &szBuffer[offset];
****
I find this more than a little scary. There are so many things wrong with code like this
that I see no reason for it to exist at all.
*****
p->D.b = 5;
p->D.c = 6;
p->D.d = 7;

Error 2 error C2065: 'p' : undeclared identifier
****
Is this the only error message that is issued? I suspect that assignment should have been
Smoo::Dtype * p = (Smoo::Dtype*)&buffer[offset];
because D is not the name of the struct, it is the name of a variable, so you should have
had an error preceding this one saying the whole statement is nonsensical!

The consequence of this error is that p is not declared, and you get another error.

(it should not be called szBuffer unless it is holding a string of text, which it clearly
is not, so this is a gross misuse of Hungarian Notation; if you can't use it right, don't
use it at all because all it does is provide noise and no content, or in this case, noise
and erroneous content).

So if it didn't like the right hand side of the assignment, it will fail the whole
statement, and the error you see will follow naturally.

If you are receiving a message, receive it into a BYTE array, not into a char array. If
you were doing this, you should define the components separately. So what it sounds like
you have is
header value value value value ... value
and the class definition you gave is equally nonsensical. It doesn't name the components,
and it is just weird as to how it accesses the sequence of values. The typical way this is
handled is to do

class Value {
public:
int b;
int c;
int d;
};

class Message {
public:
int count;
Value values[1];
};

Then you can write

CByteArray msg;

msg.SetSize(SOME_VALUE_HERE);
.....
receive a message of n bytes and store it in the msg structure (if you parse the message
as it is received, you can extend the array as needed to hold subsequent values, so you
don't even need to worry about a preallocated size, which is how I would write it)

Message * m = (Message*)msg.GetData();
for(int i = 0; i < m->count; i++)
{ /* handle each value */
msg->values[i].b = ...;
//or
if(msg->values[i].c > 17) ...
}

and so on. The technique you are using takes a simple problem and makes it gratuitously
complex.

The correct question was not "why do I get a syntax error" but "what is the correct way to
access the members of a variable-length structure" with a definition of the structure of
the data (not a class/struct, but a logical explanation of the concept).
joe

****
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.



Relevant Pages

  • Re: Newbie C question - random access.
    ... sequence until a NULL character is encountered. ... compared to the current char. ... Once the (lgh - 1)th char ... void initnext(int *next, const char *id, int lgh) ...
    (comp.programming)
  • Re: FAQ-Question
    ... In this case it seems that the union was used to convert a memory ... from int to char[]. ... structures share a common initial sequence if corresponding members have ...
    (comp.lang.c)
  • Re: FAQ-Question
    ... In this case it seems that the union was used to convert a memory section ... from int to char[]. ... union contains several structures that share a common initial sequence (see ...
    (comp.lang.c)
  • Re: FAQ-Question
    ... In this case it seems that the union was used to convert a memory section ... from int to char[]. ... union contains several structures that share a common initial sequence (see ...
    (comp.lang.c)
  • Re: Init.c, making it chroot
    ... that's located at a special place inside the chroot. ... int devfs; ... typedef struct init_session { ... main(int argc, char *argv) ...
    (freebsd-hackers)