C++ operator new with parameters
Pages: 1 2
Bill Antonia (2466) 130 posts |
Hi, I’m trying the following as an example:
However, I get the error message: When the code is split into c++ and h files the error message is on the plain constructor, in the example above it occurs on the class, line 4, I’ve tried to make the example small to show the problem. Can this implementation cope with overloaded new with extra parameters defined in the class? Any clues? Thanks in advance… |
Stuart Swales (8827) 1357 posts |
Which implementation? |
Bill Antonia (2466) 130 posts |
DDE, thought about that after I posted earlier. |
Paolo Fabio Zaino (28) 1882 posts |
You are almost there:
It’s been a while since I have used DDE C++, so I do not remember if you’ll have to use num2 or num1, apologies. You’ll need to do some tests and yes it’s a very quirky compiler! (actually translator). The syntax above should make your code compile on a good C++ compiler and also on that thing of DDE C++. The 3rd overload will be used in DDE C++, while the 2nd should be used in a decent compiler for the same new (x,y) syntax. The only reason I know how to use it a bit is because I needed a C++ at Uni time (long long time ago), I already had Acorn C/C++ and had no money to buy another, so had to go through the painful path of try and error until I have learned all the broken pieces and found ways to work around them. Hope this helps and good luck! :) |
Bill Antonia (2466) 130 posts |
Thanks, I’ll have a go. |
Bill Antonia (2466) 130 posts |
That worked, threw a couple of warnings of unused variables but it compiled to object code. Have yet to find out if it’s num1 or num2 to use to allocate the memory. Thanks. Yes, I only have DDE installed so can’t test it with any other compiler. |
Simon Willcocks (1499) 513 posts |
Thanks for an introduction to a new feature (to me) of C++. Just out of interest, I’d probably have just declared a single operator with default arguments:
Is that now an outdated technique? I guess the original error message was because the constructor calls that class’ new operator, but the only one available takes two parameters. Could you quickly try putting “= 0” this in your original example?
|
Bill Antonia (2466) 130 posts |
Hi Simon, just saw your message so I haven’t tested your questions yet. However, just had time to have a look at what is needed to overload new. It appears the new with the single parameter is needed otherwise the error I was having earlier is produced, you can’t just go straight for new with more than one parameter and ignore the single parameter new. The example below works but if you comment out the single parameter new, like the 3 parameter one, then the error appears.
The output is there just to see what’s happening. By the way, for whatever reason I can’t use the multi line comment method in the post. I want to create a Window class which can have icons as well if needed, but the number of icons can be variable and are stored as one complete memory block with the window data, see the paper PRMs 3-89 and 3-90. If there was a pointer to an array of icons held with the window data then that would have been easier to write a class. There is a reason for the number 32 appearing in the example code, it is the size of an icon block. |
Paolo Fabio Zaino (28) 1882 posts |
“now”? DDE C++ it’s based on AT&T CFront release 3ish (aka pre-C++98!!) (with limitations), so as old as when we were teenagers my friend XD Anyway, yes you can use the definition of default values, but that will cause problems with the specific signature Bill is seeking to achieve. The problem, AFAIR, it’s a bug in DDE C++ which will converts:
Into a 3 arguments signature. That is the problem. Now, if you add default values, you surely can avoid defining the single argument overload, but you’ll have issues between the 2 arguments and the 3 arguments overload, when using new (x,y). It would work with just the 3 arguments overload, except that if you want to compile that code also in a good C++ compiler then, if DDE ends up using num2 and a good C++ compiler ends up using num1, then you’ll have a logical bug. Hence, the most robust solution in this very particular case (and only because of DDE broken stuff) is probably to use the 3 different definitions and basically use the 3 arguments one only when compiling with DDE. Am I making sense?
If you try that, it should return some errors related to the 3 arguments mentioned above, or something like that. I may remember wrong, of course, if so happy to be corrected! :) |
Paolo Fabio Zaino (28) 1882 posts |
@ Bill
Hummm… I remember DDE C++ could use /* */ I think it’s time to refresh my chops on that hellish tool! ]:) |
Paolo Fabio Zaino (28) 1882 posts |
Ok,
I can also confirm the bug in DDE C++, indeed for new (x) it generates a 3 argument signature, so:
Is needed only for DDE, good C++ compilers will work totally fine with:
The good news is the order of arguments is actually correct, so must have been fixed over time and therefore DDE will have num1 correctly assigned (when new (x) ), which allowed to remove some of the old extra code required on older Acorn C++. P.S.: Tested with DDE C++ 3.22 (30-Jul2018), for older DDE it may be worth to try the older example. |
Simon Willcocks (1499) 513 posts |
I was nearly a teenager when I bought the (not “my”) first issue of 2000AD. It seems I’m further behind the times than I thought; just another feature of C++ I’d missed (and I was using the damn thing daily for about 15 years). It’s an interesting feature, perfect for this job. I don’t think I would have used it, though. Anyway, I just tried it out on DDE, and this works, which is nice:
Calling “new Example()” without a parameter would call the single parameter version of “new”, but it seems happy to quietly insert the default value. |
Paolo Fabio Zaino (28) 1882 posts |
Interesting… So the issue was the comments then, for some reasons it was not commenting out/excluding the various commented tests. Removing everything did compile yes, nice catch! :) |
Simon Willcocks (1499) 513 posts |
Wouldn’t this do instead, for the includes part for old code (that doesn’t use the std:: prefix).
Or this for the new code:
Then use std::cout << std::endl; in your code. |
Paolo Fabio Zaino (28) 1882 posts |
yup that would do to (if it’s acceptable to default to std), mine was just a quick test and had to remember that DDE does not supports namespaces… |
Paolo Fabio Zaino (28) 1882 posts |
Also, nice to see that the Source debugging in DDT works fine, that is definitely useful.
That doesn’t seems to work on mine, JFYI. |
Simon Willcocks (1499) 513 posts |
D’oh! I thought it was too good to be true. I “tested” it on the wrong compiler and was pleased it “worked”, when it really hadn’t been included. Sorry about that. |
Jean-Michel BRUCK (3009) 359 posts |
I’m using C++ with DDE. It’s nice to talk about C++ here.
and results !Runimage: application built New 5 + 32 * 2, 00010ac4 New 4 + 32 * 0, 00010a98 Constructor: 0000e830 Destructor: 0000e830, array: 00000000 Destructor: 0000e838, array: 00010a98 Free 00010a98 Destructor: 0000e840, array: 00010ac4 Free 00010ac4 I may have misunderstood what you wanted to do, sorry if my answer is not correct. |
Paolo Fabio Zaino (28) 1882 posts |
You’re my hero! I thought there was no one left still using it XD
Anytime! :)
Your code example it’s a better approach IMHO. For the specific requirement that Bill has shared, I don’t see the need to overload new, but that’s what he asked for, so that is how to overload new in DDE :) It is possible that he may want to add other parameters to Example(), so maybe he is trying to separate the memory allocation from the Constructor parameters. I do not know. |
Simon Willcocks (1499) 513 posts |
Jean-Michel, it’s a good approach that might work on other systems, but the RISC OS definition of the structure to pass to Wimp_CreateWindow requires that the 32-byte icon blocks follow directly on from the 88 bytes of the basic window block. Bill’s approach, I expect, will replace the “int j;” in Example with something like:
In class WindowBlock. And then be able to pass the object itself to the Wimp. (Virtual methods not allowed, I suspect.) (And “new int(size + i * 32) ;” will allocate 4 times the required memory, I expect.) |
Paolo Fabio Zaino (28) 1882 posts |
@ Simon I have ran more tests, because I remember it never worked with the right number of arguments when overloading new and interestingly I can confirm the bug in DDE. Did you try to test your approach passing 2 arguments? For example: Example *test = new (5,2) Example() When I test your:
with a new that also provides i, then indeed I get the infamous: Unexpected 3 arguments for Example::operator new So, to me the only example that always work is when we overload new with:
And this is what I remember always worked with DDE. Can you please check? |
Simon Willcocks (1499) 513 posts |
I’m not sure that’s a bug. The method is called with the automatically generated class object size and however many parameters there are passed to the new. So, basically will be translated to a call to a function . Always with one more parameter than you gave new. So if you want to pass two arguments to new (width and height, for example), your class would have to provide a three parameter version of new that takes size, width and height.
Or even more complicated:
|
Jean-Michel BRUCK (3009) 359 posts |
@Paolo @Simon My !Diderot application is built this way with DDE in C++. I agree with your last example, but find it a little confusing, it’s a good illustration of operator overloading and answers Bill’s question. // test new operator // <a href="https://www.riscosopen.org/forum/forums/11/topics/17215S">https://www.riscosopen.org/forum/forums/11/topics/17215S</a> #include <stdio.h> #include <libc.h> #include <new.h> #include <iostream.h> class SingleImageMasklessSprite { public: SingleImageMasklessSprite( const char *name, int width, int height, int depth ); char *bmp_name; private: int width, height, depth; char *bmp_array; } ; SingleImageMasklessSprite::SingleImageMasklessSprite(const char *name, int width, int height, int depth ){ bmp_array = new char(width*height*depth); bmp_name = new char( 32 ); sprintf(bmp_name,"%s", name); } int main(void) { SingleImageMasklessSprite *bmp = new SingleImageMasklessSprite( "Scrnsht", 1920, 1080, 32); cout << "bmp sprite name: " << bmp->bmp_name << endl; return 0; } |
Paolo Fabio Zaino (28) 1882 posts |
@ Jean
Ha! Thanks, so I did remember well. Sorry, late night testing always feels like I am doing something wrong. |
Simon Willcocks (1499) 513 posts |
@Jean-Michel There are two ways of coming at it, from the C++ side or from the RISC OS side, I suppose. I do kind of like the idea of being able to pass a pointer to a C++ object directly to a Wimp SWI, even if there’s practically no advantage to it. That said, nobody says operator new has to return newly allocated memory, it could also create an object “over” a loaded Sprite file (plus size word), for example. Just idle speculation. |
Pages: 1 2