Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ Programming
➜ General
➜ Multi-Dimensional Char Arrays -- HELP!!
Multi-Dimensional Char Arrays -- HELP!!
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Pages: 1
2
3
4
Posted by
| Isthiriel
(113 posts) Bio
|
Date
| Reply #45 on Sun 20 Jan 2008 09:51 PM (UTC) |
Message
|
Quote:socket.cpp: In function `bool new_socket(int)':
socket.cpp:318: warning: invalid conversion from `void*' to `D_SOCKET*'
socket.cpp:356: warning: invalid conversion from `void*' to `LOOKUP_DATA*'
socket.cpp: In function `void handle_new_connections(D_SOCKET*, char*)':
socket.cpp:1008: warning: invalid conversion from `void*' to `D_MOBILE*'
Ok, you have a bunch of void* -> SomethingElse* typecasts. In C the syntax for that is just (SomethingElse*).
C++ has RTTI and needs three different kinds of typecasts, static_cast, dynamic_cast and reinterpret_cast.
Because you're casting from void* I think reinterpret_cast is the appropriate one to use, so where is says:
(D_SOCKET*) stuff
you need to replace that with:
reinterpret_cast<D_SOCKET*>(stuff)
Quote:socket.cpp: In function `bool read_from_socket(D_SOCKET*)':
socket.cpp:509: warning: comparison between signed and unsigned integer expressions
That's fairly straight forward, you have a comparison operator (==, <=, >=, !=) operating on two expressions, one of which is signed and one of which is unsigned. Explicitly cast one of them to the type of the other.
| Top |
|
Posted by
| TheTraveller
(23 posts) Bio
|
Date
| Reply #46 on Sun 20 Jan 2008 10:31 PM (UTC) |
Message
| Ahh ok, I'll try both your suggestions and let ya know the result. I'm curious though, why would C be fine with all these redeclarations and whatnot but C++ is not? Does C++ have stricter syntax guidelines or are they just different somehow?
| Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #47 on Mon 21 Jan 2008 01:26 AM (UTC) |
Message
|
Quote: C++ has RTTI and needs three different kinds of typecasts, static_cast, dynamic_cast and reinterpret_cast.
Actually it doesn't need the new cast syntax; you can use the C one just fine. The thing is you have to explicitly cast it, whereas C is a little more happy-go-lucky about implicit casting. And C++ doesn't necessarily have RTTI either; you need to turn it on. (Granted, some compilers turn it on by default.) If you don't have it on, then a dynamic_cast isn't actually dynamic. But the point is that it won't necessarily affect how you cast things.
Quote: Explicitly cast one of them to the type of the other.
Well, better yet would be to use the same sign both times or figure out why the signs are different; maybe it is incorrect to be casting. Casting these things can sometimes result in data loss or otherwise incorrect data. How are you going to cast -1 to an unsigned int? (-1 being a common error value returned by some routines)
Quote: Does C++ have stricter syntax guidelines or are they just different somehow?
Mainly just stricter guidelines. In general g++ tries harder to make sure you're not shooting yourself in the foot. To be honest I'm not sure if it's something in the C++ standard, or just g++. Never really looked at the standard... |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Isthiriel
(113 posts) Bio
|
Date
| Reply #48 on Mon 21 Jan 2008 02:30 AM (UTC) |
Message
| Doesn't having a virtual function declaration in a class force that class, and all classes that inherit from it, to have a pointer to a function table, which is the basis for C++'s RTTI? (And classes that don't have any virtual functions in their class hierarchy are somewhat indistinguishable at runtime?)
I said fairly straight forward. Casting large unsigned values to signed integers is problematic. But in a mud most of the unsigned 32-bit ints are used to store values in the range 65536 to a few million and if the values in question are never over two billion then you can cast everything to signed long and it will be fine.
Given that it's in a function called read_from_socket it's probably either a size_t being compared to a (signed) constant, or a character type mismatch signed char vs unsigned char. In the case of the size_t (and given that we're reading from a socket) casting down to signed long won't lose any information. And the signed char vs unsigned char casts preserve the character information, if not the strict ordering (so == and != work, but <= and >= aren't guaranteed to).
Usually casting -1 to an unsigned (and the reverse, unsigned -> signed is more common) produces MAX_INT - 1, depending on the width of the type you're dealling with (ie (char) -1 => (unsigned char) 255). That preserves the bit equivalence under Two's Complement though again it can destroy the ordering.
On the topic of flags, does -ansi do anything for g++? Under gcc it creates warnings for non-ansi C idioms iirc. | Top |
|
Posted by
| Nick Gammon
Australia (23,158 posts) Bio
Forum Administrator |
Date
| Reply #49 on Mon 21 Jan 2008 04:22 AM (UTC) |
Message
|
Quote:
Does C++ have stricter syntax guidelines or are they just different somehow?
Technically they are different languages, although there are obvious similarities.
There is no specific requirement for something that works under C, to work under C++. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #50 on Mon 21 Jan 2008 04:30 AM (UTC) Amended on Mon 21 Jan 2008 04:31 AM (UTC) by David Haley
|
Message
|
Quote: Doesn't having a virtual function declaration in a class force that class, and all classes that inherit from it, to have a pointer to a function table, which is the basis for C++'s RTTI? (And classes that don't have any virtual functions in their class hierarchy are somewhat indistinguishable at runtime?)
Yes and no... the vtable is just a function lookup table, and there is not necessarily any type information associated with it. You can use virtual functions and not have any RTTI. g++ has the option -fno-rtti to turn off RTTI -- but that won't turn off virtual functions...
The main point though is that you can do casts in C++ without using the new C++ cast operators.
Quote: That preserves the bit equivalence under Two's Complement though again it can destroy the ordering.
I know of very, very few cases where I care about bit equivalence but not about ordering; I know of lots and lots of cases where I care about ordering but not bit equivalence...
Quote: On the topic of flags, does -ansi do anything for g++? Under gcc it creates warnings for non-ansi C idioms iirc.
Citing man g++:
"In C mode, support all ISO C90 programs. In C++ mode, remove GNU extensions that conflict with ISO C++."
Quote: There is no specific requirement for something that works under C, to work under C++.
Well, while that is true very technically speaking, the design of C++ went to an awful lot of effort to make it work as long as you're doing things properly. It also works very hard to make C++ behave like C in terms of compiled assembly unless you use C++ features. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Nick Gammon
Australia (23,158 posts) Bio
Forum Administrator |
Date
| Reply #51 on Mon 21 Jan 2008 04:40 AM (UTC) |
Message
| I have mixed feelings about run time type information (RTTI).
One the one hand it is handy to be able to work out what things are at runtime, there is an argument that this should be part of application design (eg. a "type" field in the data).
I agree C++ has tried hard to be compatible with C, however an example is from SMAUG where you needed to change the word "class" in the code in many places because it became a reserved word.
You could also argue that type casting is one of the uglier aspects of C. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #52 on Mon 21 Jan 2008 05:05 AM (UTC) |
Message
|
Quote: I have mixed feelings about run time type information (RTTI).
One the one hand it is handy to be able to work out what things are at runtime, there is an argument that this should be part of application design (eg. a "type" field in the data).
I agree; I've never used RTTI from C++, because it doesn't do the RTTI that I want. I implemented my own RTTI framework for my MUD in which all classes inherit from a "CodeObject" class that contains information like the class name, a way to print out basic/detailed information, etc. That is the kind of runtime information I care about: e.g. getting the class name at runtime to print it, not being able to downcast to subclasses.
(Yes, I realize you could try downcasting to subclasses and see where things fail and eventually work out the exact class, but that is tedious and inelegant at best...)
Quote: I agree C++ has tried hard to be compatible with C, however an example is from SMAUG where you needed to change the word "class" in the code in many places because it became a reserved word.
Agreed. Actually I don't understand why this is a problem because they should be able to figure out from context if a keyword is being used as the actual keyword or as an identifier. I guess it's simpler to handle things this way.
Quote: You could also argue that type casting is one of the uglier aspects of C.
Generally agreed, although it tends to be useful when you're doing rather low-levelly type stuff. It's also useful if you need a generic parameter passed to a function -- like the thread 'main' function in pthread -- but the library cannot know the type ahead of time. Still, it requires a fair bit of grokking to use correctly... |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| TheTraveller
(23 posts) Bio
|
Date
| Reply #53 on Thu 24 Jan 2008 10:08 AM (UTC) Amended on Thu 24 Jan 2008 10:58 PM (UTC) by TheTraveller
|
Message
|
Quote:
Because you're casting from void* I think reinterpret_cast is the appropriate one to use, so where is says:
(D_SOCKET*) stuff
you need to replace that with:
reinterpret_cast<D_SOCKET*>(stuff)
This didn't work. When I tried it, all I get is a parse error. I couldn't figure out whether you were referring to the declaration at the top of the function or the code that contains "(D_SOCKET *)" later in the function, so I tried each individually. I also thought the use of "<D_SOCKET*>" might be an error, so I tried "reinterpret_cast(D_SOCKET *)" as well and it still gives me a parse error.
Could you please clarify that code example you posted? Every variation I try on your suggestion results in a parse error.
| Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #54 on Thu 24 Jan 2008 11:51 AM (UTC) |
Message
| The reinterpret_cast stuff is likely to be a red herring; I wouldn't pursue that route any further and you don't need reinterpret_cast anyhow. Please post these lines of code so we can see exactly what is going on:
socket.cpp: In function `bool new_socket(int)':
socket.cpp:318: warning: invalid conversion from `void*' to `D_SOCKET*'
socket.cpp:356: warning: invalid conversion from `void*' to `LOOKUP_DATA*'
socket.cpp: In function `void handle_new_connections(D_SOCKET*, char*)':
socket.cpp:1008: warning: invalid conversion from `void*' to `D_MOBILE*'
|
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Isthiriel
(113 posts) Bio
|
Date
| Reply #55 on Thu 24 Jan 2008 12:03 PM (UTC) |
Message
| reinterpret_cast<type>(object)
dynamic_cast<type>(object)
static_cast<type>(object)
Are the correct forms.
I was referring neither to the parameter declarations, nor the variable declarations. I was expecting you to have lines of the form: var = (D_SOCKET*) func();
where the (D_SOCKET*) is a cast, and I thought you might need to specify what kind of cast you wanted.
As David Haley pointed out in his post of Mon 21 Jan 2008 01:26 AM (UTC), the issue isn't the type of cast in this case, it is the lack of an explicit cast from the function(s) (malloc? calloc?) that are returning void* and that the code is attempting to stuff into various other types (D_SOCKET*, ...) OR you have a void* you're trying to stuff into a function that is expecting one of the other types.
So you have something like: var = malloc(sizeof(D_SOCKET));
That really should be: var = (D_SOCKET*) malloc(sizeof(D_SOCKET));
(You will note that all of the return values from the calls I made to malloc() in my earlier posts are explicitly cast to the type of the variable the return value is being stuffed into.)
Unfortunately I can't really be more specific than that. If you can post the lines in error and their context I might be able to correct them. | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
138,449 views.
This is page 4, subject is 4 pages long:
1
2
3
4
It is now over 60 days since the last post. This thread is closed.
Refresh page
top