problem printing out c++ enum

Hi,

Here's the information: VS2005, using c++. I am trying to print out an enum value (as a string), and it works the first time, but not during any subsequent times. I'm wondering if there is just some obscure thing I don't know. Below is my code, Here is an explanation:

We have a custom TCP channel based object that can send and receive commands. That is what 'channel' is. Note that myEnum is just an enumeration with a bunch of commands in it. Please note that receiving the first command works fine and prints out fine too. However, cmd2 will not print out. What is even more bizarre is that the little floaty box thing when stepping through the program in Visual Studio DOES confirm that cmd2 is correct!!! It was received! But there is nothing on the console when printing.

You may note that the ReceiveCommand function takes a reference. In reality, it takes a pointer to a myEnum. So, I have tried all sorts of things with regards to using pointers, and printing out the addresses of the commands using both the & and the * operators, all to no avail. No matter what I do, the first one prints and the second one doesn't.

Thanks for any help.

Regards,
Michael Kolakowski

P.S. I assign this a difficult rating, only because it's so simple and yet not working....what more could I be missing?

Who is Participating?

John,
I'm not sure how much experience basti has, probabably a fair bit and i've been in the software industry for a while now, it is hard without seeing all the code but we both suspect there is something up with both the handling of pointers and the use of CONST.

I suspect that the problem with your code might be that it does not conform to the standards. i.e. the way it is written relies on an undefined action, it will work sometimes but is not guaranteed, like the code previously described:

std::cout << x << "\n"; // who knows what it prints? on mine if prints 4."

It might pay to revisit parts of the code.
My advice from here would be to make your ReceiveCommand function look like this:
int ReceiveCommand(myEnum *cmd)
call it with
ReceiveCommand(&cmd); where cmd is defined myEnum cmd=myEnum(0); //making sure memory is allocated

Inside ReceiveCommand call recv with this

recvStatus = recv(conn,(char *) cmd,sizeof(myEnum),0); //consider using 1 instead of sizeof(myEnum), you actually only want 1 digit from recv - this is just my guess.)

then make it compile without the use of any extra * or &'s, unless absolutely neccesary.

*********************************
The block of string text you are talking about is the << operator overload function for the myEnum datatype. It provides an easy way to print out strings, such as "LOG_IN" rather than dealing with a number. Your code, as is, would print '1' mine would actually print "LOG_IN."
To use, its the same as any std output.
std::cout <<cmd;

When you are stepping through the program, the cmd2 prints well, right?
But when you run the program, it is not working??
Please make sure that you are executing a debug version. Then only the the cmd2 will be printed, as there is a #if _DEBUG clause.

HTH
Saji R

0

JohnSantaFeAuthor Commented: 2006-06-22

No, it does not print...ever! I can run it in debug, release, whatever. I can remove the #if so it will always run and the same thing happens...it never, ever, prints out. But it does show up in the intellisense thing. Quite frustrating I might add.

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

There are two things I'm thinking.
1. I'm suspicious of the #if
so can you please insert the foll before the #if and try. Understood that you've tried removing #if line.

#ifndef _DEBUG
#define _DEBUG
#endif

2. Does any of the second line print out?? i.e. this bit
"We should have received GET_BITS. Command received =="
If none of it is printed then I would be even more suspicious of your #if.
If the text does print then what value are you getting from the cmd2 printout.

Note: both have been edited slightly, but this shouldn't affect things. Thanks again.

Michael Kolakowski

0

JohnSantaFeAuthor Commented: 2006-06-27

This is regarding the comment on 6/25/06:

1. I tried that and it didn't do anything. It just skipped over that part because I was building it in debug.

2. That's a very good question, and one I didn't clarify earlier. Yes the second line prints out...it just prints nothing for the command. So, it looks like this:

"We should have received GET_BITS. Command received == "

Again, I can get it to print an address or pointer or whatever...but when I dereference the pointer (or reference variable) nothing comes out. Plain old nothing. But something is there, because the program runs fine. So, I shouldn't be complaining too much. I'm just so befuddled as to why the first one works, but the second one doesn't.

As a further clarification to my earlier code post: the enum is actually called channelcommand. I was trying to hide as much project related detail as possible because we are not supposed to discuss it, however, I see that I let the cat out of the bag in the receive command function, so consider it explained.

You are passing an argument of type myEnum to the member function TCPChannel::ReceiveCommand(const ChannelCommand *).
That is bound to eventually cause an exception. I suspect your code crashes upon first access to the variable cmd.

Also, the member function TCPChannel::ReceiveCommand(const ChannelCommand *) cannot not possibly alter its argument, as it is const.

If ReceiveCommand is to return incoming TCP data, the declaration of this member function ought to be:
int TCPChannel::ReceiveCommand(ChannelCommand *cmd)

Your are using the ChannelCommand object as second argument to the recv(..., cmd, ...)
In order for this to work, ChannelCommand must be of type char* and already allocated.
It would help to know what the ChannelCommand class looks like.

Finally, assuming ChannelCommand represents a string, the returned buffers cmd, cmd2, respectively MUST be terminated with '\0' in order for cout to function properly. Otherwise there is no way of telling how long the string is. (I am assuming ChannelCommand is somhow derived from a string class.

Try removing the const from the ReceiveCommand function (also the prototype).

This would explain why you could see it working when tracing it in visual studio.

J.

0

JohnSantaFeAuthor Commented: 2006-06-28

Guys....you got me all excited by your posts, but alas, they still were not the solution. Allow me to explain and address questions:

1. Remember, I changed my code to hide project details, but forgot to change all of it. Hence any inconsistencies.

2. There is no channelcommand class. It is an enum. That's it. Pleae replace channelcommand with myEnum or vice versa. Whatever floats your boat.

3. Finally, (here's the part the got my hopes up), the const trick doesn't work either. Note that ReceiveCommand takes a constant pointer to a channel command, which is different from a pointer to a constant channel command. So, indeed, it CAN modify the variable, because the variable is not const, it just can't change the pointer. Shucks...

So, it looks like we are back to square one again!

Michael

0

JohnSantaFeAuthor Commented: 2006-06-29

Hi,

Seeing as this appears to be so hard, I thought we'd have a double points Thursday! Woohoo.

It is quite hard to spot a logical mistake in some code when it is covered up by several others.
Why not just create a code snipped that would theoretically run, so we can talk about your actual problem ;-)

It's just not so intuitive to interchange types and classes - this is not VB you know ;-)
And how about the 'const' argument to ReceiveCommand() - is that also a disguise, so we won't notice it beeing changed ...

As to your point 3:
# const Fred* p means "p points to a Fred that is const" — that is, the Fred object can't be changed via p.
# Fred* const p means "p is a const pointer to a Fred" — that is, you can change the Fred object via p, but you can't change the pointer p itself.

The recv function will alter the memory pointed to by 'cmd', not cmd itself. I tried to explain that you will need to allocate memory at 'cmd' if you are using it as you do:
recv(conn, cmd, nBytesAllocatedAtAddressCmd, 0);

Thanks everyone for all your efforts in trying to help. Puta, it appears your code does closely match my code. I was even thinking of going the route you did. I have not had the easiest time finding information online about enums. But I did notice this: Puta, you had if statements in your code of the form:

if (cmd == WHATEVER)
std::cout << "WHATEVER" << std::endl;

Whereas I was trying to directly output the Enum (std::cout << "enum is: " << cmd << std::endl;). Is that even valid? If not, then why does it work the first time for me? That's the confusing part. I could understand if you just couldn't print out enums, then I would have gone with the 'intermediate' block of code to get the string representation -- but it DOES work!!!! WHY?

By the way, I already tried doing a block of code like yours, Puta, to get the string representation of my ChannelCommands. It works just fine. So, I guess I'm maybe being picky and esoteric in really insisting on sending the enum (ChannelCommand) to standard out.

I wanted to address some of your comments. I will do so now along with your latest response. First, your message from 6/30 at 2:56:

I did not think the code was so complex that a few typing mistakes would hurt it. We're experts here, right? Also, the tone of your e-mail (yes, I know electronic communications are awful for connotation) seems to indicate near sarcasm to me. I want you to know I'm not trying to hide anything. Regarding the const problem, I mentioned that I tried it both ways -- it still didn't work. And, regarding the pointers, I apologize. It's always such a pain to keep those straight. Also, I don't program in VB, and I'm actually a decent programmer. I 'do' know the difference between types and classes, however Python and the str() function are great! Finally, I don't think I mentioned this, but I tried allocating memory for my cmd using the new operator. IT DID NOT WORK! I tried putting it on the heap, the stack, using pointers, using new, you name it...all to the same results: It just prints nothing.

That said, I'd now like to address your latest post. On my computer, I do not get the results you claim. Operator << does NOT take my enum as an integer unless I specifically cast it as thus:

std::cout << (int) enumvalue << std::endl;

Secondly, I cannot stress this enough times: For the first statement in my code it actually works. It actually prints out the string representation of the enum value. Using your example, that is:

std::cout << one << " : " << two << std::endl;

yields the out put:
one : two

Please see my very first post for further clarification. The first statement works, the second doesn't. It's that simple. Which makes it all that much more frustrating for me. And the heck with the #if _DEBUG - guess what? taking that out made no difference either. I wouldn't be posting here if they both worked or both didn't. If they both worked, obviously I'd be fine, and if they both didn't, well, I'd have just assumed that you can't send an enum to std::cout and would have used a switch or something to get the string representation. But, again, one works, the other doesn't and there is no discernable difference between the two.

Note: I did try figuring out someway to append a '\0' on to the enum...but I'm not an uber programmer, so that venture was met with no success. I thought perhaps if I could be sure it was null terminated (though I thought cout was 'smarter' than printf) that might help. Again, I couldn't figure out how, an enum is not a char buffer, so memcpy didn't work among other things.

I actually was beeing sarcastic and I am sorry for that. At the same time though I was trying to make it sound very moderate and never meant to depreciate you.
The electronic communication won't transmit tone of voice - will it.

It is sometime really hard to tell on what level of difficulty one is supposed to answer the question.
So given the type mixups, given the const* pointer, given the usage of the recv() function I had to assume these were you troubles.

I still believe you cannot reasonably discuss a piece of (possibly errornous) code that has been been altered the way you did.
You know your code best by the time of posting. We must believe that all you are posting is of certain relevance to the problem - otherwise you wouldn't have posted it.

I am sorry for generalizing my statement about the implicite enum -> int cast. My compiler does it, yours obviously doesn't.
However, given that your compiler prints out " one : two : three" I will have to resign now as I obviously know nothing about programming envirnonments other than my VC6++
*sarcasm* -> me.

Again I am sorry for picking that harsh tone of voice
Sebastian

0

JohnSantaFeAuthor Commented: 2006-07-05

Well, I think it's time to close the book on this one. I've had enough. First, a few things to say:

Sebastian, thanks for the apology and don't sweat it. I have a pretty thick skin so I don't take offense too easily. Besides, you never know if you are dealing with a total noob or someone who has programmed in 12 languages. Perhaps there should be a way to list your experience so you experts have a basis for your response. Maybe this could be a feature added to the site? I've read that even Eric Raymond gets stumped from time to time and he's written compilers for fun, something I've yet to do!

You are probably right about discussing code, but again I only altered names and not the code. I just forgot to change all of them. ;) Also, for what it's worth, only the output code is mine. The enum, receive command, and such were written by someone else.

Putanerd, thanks again for your response. On a whim, I thought I'd try it one more time. I removed the const, called receive command as you suggested and it still doesn't work. ~sigh~ Perhaps you are right about it being an undefined result. In any case, my solution is to do this: