Amiga.org
Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: Steady on July 21, 2004, 01:21:14 PM
-
Hi all.
I have what may be a really dopey question.
The 3.9 includes are riddled with 'void *' types which C++ doesn't like at all.
I was wondering what the best way around this is in GCC 2.95.x.
Is there a switch to ignore the problem, a different version of the include files (perhaps with replacement ULONGs) or something else?
This has stopped me using C++ in favour of C in the past and I probably don't have to. May as well sort it out now.
Any help would be appreciated.
-
Hmm, not sure I follow you.
C++ has no problem with void* at all, in fact, C++ introduced the void pointer, which C later adopted (rather than using unsigned char* etc).
I certainly have experienced no problems with the OS3.5 or 3.9 includes relating to void*. In fact the only problems I have ever encountered was a scope of resolution problem to do with library base names that happen to have global pointers of the same name (eg IntuitionBase* IntuitionBase), which was resolved by using :: operator to prefix the pointer.
What C++ doesn't like is implicit pointer conversion from void, which is allowed in C, or from any type to another that isn't defined directly or in terms of base/subclass heirarcchy.
So you can't do things like
int* n = AllocVec(1024, MEMF_PUBLIC);
since AllocVec returns APTR (usually typedefed' as void*).
The OS was written with in C in mind, and as such has some of C's legacy problems that mean some example sources may not compile out of the box in C++ mode, but is quite managable from C++ provided you spot any violations of C++ typing rules.
It sounds like you have a configuration problem. Something I hate about gcc is that it is such a {bleep} to set up usually...
Good luck :-)
-
Thanks for the reply Karlos.
It is problems like the AllocVec() one you mention above that return APTR as defined in the includes. APTR is defined as void * and usually these are typecast to what I actually want. I will have another look tonight and see if I can get clued up and have a working example.
Actually, I just noticed this in the exec/types.h v40:
#ifndef APTR_TYPEDEF
#define APTR_TYPEDEF
typedef void *APTR; /* 32-bit untyped pointer */
#endif
Can I assume that I can fix my problem by putting the following before exec/types.h is included?:
typedef unsigned long *APTR;
-
Hi,
You don't need to redefine anything. You just have to manually cast from void* to type* in C++ since this implicit conversion is forbidden (part of C++'s stricter rules).
To use eg. AllocVec(), cast the return value to the pointer type you require, eg
int* n = (int*)AllocVec(1024, MEMF_PUBLIC);
...and that's it. You really don't need to modify any of the headers or anything like that - in fact doing so is a very bad idea since you are making your code dependent on non standard (no matter how much you don't like the defined standard itself ;-)) amigaos headers.
-edit-
Note it's not just amigaos that has this problem. Even the C standard library malloc(), calloc() and realloc() all return void* and so need manual casts in C++ if they are to be assigned to a typed pointer (like int* etc).
Essentially, casting from void* to type* is dangerous which is why C++ banned implicit conversion. When you explicitly cast as above, you as the programmer are taking responsibility.
-/edit-
As it goes, for simple allocations of this kind and stuff you should really use new[] and delete[] anyway. Use AllocVec() when working close to the OS, or have a specialist requirement (eg allocating memory in chip ram or whatever - I've personally created my own new[] operators for this kind of stuff in the past.
-
Beauty. That's what I was looking for... couldn't see the forest for the trees. Sometimes it's easy to miss the obvious when you come across something slightly different.
Thanks for the help.