New DDE C++ (CFront) video released: DDT Debugging techniques for C++ In-Depth
Paolo Fabio Zaino (28) 1882 posts |
Given that it seems there are quite a few interested in the old DDE C++ CFront (and not only in the traditional RISC OS community), I managed to find some time to make another video for it. This time is about sharing some (apaprently still undocumented) debugging techniques that I have found back in the ’90s when learning C++ (obviously on RISC OS, in particoular on my old RiscPC). Techniques in this video show how to write DDT friendly C++ sources and how to debug private members variables, plus there are some extra bits on how strings are stored in memory and few other minor things. Hope the CFront C++ group will enjoy it (and yes I know Druck will not! XD ) Also I started to create a playlist just for DDE C++ videos, you can find it here: https://www.youtube.com/playlist?list=PLEnraaJ9VQfUNlMvE9PMeJxK7_UbnBcRk Sources for the video, as usual, here: https://github.com/RISC-OS-Community/DDECPP-Tutorials Enjoy! :) P.S. obviously “enjoy” is pronounced with a sarcastic tone when it refers to C++ XD |
Jean-Michel BRUCK (3009) 359 posts |
Bonjour Paolo Building wimp apps is simple by reusing code from a “Model” that uses the Toolbox. I use many examples of; https://cplusplus.com/reference/ which work with DDE and STL (Miles Sabin), afte after a slight adjustment. @Paolo I can make the code available, I didn’t think anyone would be interested. A vintage programmer. |
Paolo Fabio Zaino (28) 1882 posts |
Hey Jean,
Most likely also because it doesn’t work with it straight out of the box, but we’re working on it! lol – Thanks for watching the video :)
Sure, the more examples, the better :)
IMHO, the big mistake made in the 90s from the community with CFront, was to judge it as a non-complete C++, which is true, but miss the advantages that it brings to DDE C. In the video some of those are shown, more will come. I see it as “C with Objects”, which makes DDE C way better than it is when used as just C. Unfortunately this is a community that likes to complain a lot, instead of focusing on being creative and use tools in new ways. This is ok, I mean everyone is entitled to see things the way they prefer. For example: combining my vector library with DDE C++ makes it extremely simple to implement very complex applications on RISC OS and that also use way above the memory limit imposed by all RO releases. I am now workin gon a new version of it that will also help in slicing Application logic in a very simple way. So, stay tuned on this it you’d liek to see what is possible :) Maybe, through a set of videos some people will figure out that C with Objects is better than just C and that DDE C++ is not a complex as C++17/C++20/C++23, so it’s actually very easy to learn (as long as one is willing to accept the limitations). For instance, Sprow and Steve Revill, recently mentioned it would be nice to rewrite the WIMP in C. In reality, once that insanity of having Task Management in the WIMP will be moved outside of the WIMP (which should have happened long, long time ago!), then it would be even easier and nicer to rewrite the WIMP in C++ which is the perfect approach (zero cost abstraction OOP) to implement a more coherent and better WIMP and (mostly) ToolBox. But then again, this comment (most likely) will be received as an “attack” to some (invisible) “laws” that states that C is the only way etc… So, I’ll let the shower of “defensive” responses take place while drinking my coffee and thinking: “ok, another opportunity to be constructive lost in the mist of religious-developments” (I hope I am wrong). To get back on the topic, CFront IS old, but it’s still fun to use, countrary of modern C++ which has become a nightmare to use… A software engineer that has been around for a very long time now1 1 Just refusing to use the term vintage lol I do code on modern systems and with modern methodologies and programming languages, so my age doesn’t count! (does it?) XD |
Steve Pampling (1551) 8170 posts |
Based on 30+ years of experience in an IT support role, I think can honestly say the majority of this community doesn’t complain “a lot” That might be because there is a higher proportion of the vocal user base that have some sort of IT knowledge. |
Rick Murray (539) 13840 posts |
We…complain? Jeez. Go to the Daily Mail. Pick any story (but preferably ones about Brexit, migrants, or Meghan) and read the comments. What goes on here? Barely more than pub banter. |
Rick Murray (539) 13840 posts |
The law isn’t invisible, it’s just a reality of the fact that within the RISC OS realm (OS+DDE), your options are basically: BASIC, assembler, or C. You can’t write an OS in BASIC. We have one in assembler and that’s the problem. So the only other choice is C. If you think it might be better in Rust or whatever other trendy language is popular right now, cool. I have no problem with that except for the itty bitty issue of “where’s the compiler?”.
Coffee. Pah. There’s your problem. Coffee. It’s clouding your judgement and making you think Cfront is an actual language rather than a Eldritch Abomination that was neither C not C++ but some sort of halfway house on the edge of reality. It is a shame the DDE doesn’t have a real proper C++ compiler. But it is what it is.
Okay, another opportunity to be constructive lost because the poster decides that being rude is a good look. Trust me, insulting people only makes them want to work with you if you’re a notorious celebrity chef. For the rest of us? 🎤⬇️ |
Paolo Fabio Zaino (28) 1882 posts |
Not insulting, there is a quite long list of “no DDE C++”, so it’s just a fact. That includes me too BTW, again if we think of CFrotn as C++, not a C with Objects. Subtle difference that went ignored.
Not the entire OS, just the WIMP (and without tasks management).
+
Not sure where this comes from, if you rewrite an entire OS, you can pick any compiler that can target your HW platform. Beside all that stuff you’ve posted: RISC OS has an almost complete C++ (in GCC, just don’t use exceptions and for low level coding you wouldn’t use them anyway). In general my experience with writing entire OSes in C++ is not very good (different story for Rust), but again MOST (and I repeat MOST) desktop UIs1 that people are using these days are written in using some degree of OOP or are fully based on OOP frameworks, here is a list before this conversation gets out of hand (as usual): 1) KDE (Qt framework) On a more serious comment: there are merits on using OOP languages when writing WIMPs (obviously when such languages offer zero cost abstraction, that’s even better). Nothing against C, but procedural approaches can create cumbersome APIs when one wish to have UIs capable of delivering complex Windowing and gadgets.
My intention wasn’t to be rude, however strong opinions (and language wars) have always been part of this community historically, so if that is now bad, I am actually happy to hear it :) My personal opinion on the matter is pick and test the best tool for the job, that includes not only programming languages, but also architectures. However, that is a completely different discussion, ’cause the lack of an abstracted API on RO will prevent almost any approach from being viable without breaking compatibility with the past (or doing funambolic designs). 1 And so, my comments are limited only to UIs, not entire OS. <—- |
Rick Murray (539) 13840 posts |
Nothing special about us. People have ranted over Amiga vs Atari. Windows vs Linux. Android vs iOS. BMW vs Audi… Pick any two things, literally any two things (Taylor Swift vs Dysons) and in some dismal corner of the internet there’s a heated debate over which one is better (Swift, obviously, because Dyson is a hypocritical arse).
This. I keep saying that any future incarnation of RISC OS, should it ever come to be, should be processor agnostic. Sure, it should run on a 64 bit ARM. But if it can’t also run on IA64, MIPS, and so on, then really we’re doing it wrong. |
Paolo Fabio Zaino (28) 1882 posts |
I agree with this. I am not a believer of the 64bit RISC OS (as it is now). But not my place to say if it will happen or not, I am not working on it, nor I am planning to. I am already strugling to finish what I have on my plate with the very little free time I have got left (especially recently…).
+
XD
This is true, but all these examples aren’t what I was refering to. My point was on complaining about what we have. More details to come. As I mentioned already, and not intended in a rude way, I had enough of forum discussions, they don’t bring anything. It’s better to use the small time I have for RO to show what is actually possible, better if over some video and make some code available. |
Steve Pampling (1551) 8170 posts |
In a saner (possibly still not sane) implementation, “TaskManager” would do all the task management/task switching, and the keyboard handling would – nope, cling to sanity, don’t go thinking about that |
Paolo Fabio Zaino (28) 1882 posts |
XD Yeah, I actually had a similar thought after I typed about tasks management! And (as you), then told myself… nah just stop thinking about it… But, on other news, I am fighting to build a global short cuts handler. After some suggestions from Nemo, it has got in a better shape, now I need to add the infrastructural code to handle configuration files for 3rd party apps to let it know they are requesting key combination X and how that combination has to be handled (for instance, only when the requesting App is running, or also when it’s not etc). Then a touch of SWIs to allow requests updates and, the boring part, add a configuration UI to it so the user can manage all active short cuts and also decide how to handle when two Apps compete for the same short cut sequence. Hopefully there may be a new DME component soon, depending on how much time I have to work on the above. |
Rick Murray (539) 13840 posts |
Two apps enter, one app leaves. Two apps enter, one app leaves. Two apps enter, one app leaves. Two apps enter, one app leaves… |
Steve Pampling (1551) 8170 posts |
and has the focus. Certain apps/tools seem to think they have exclusive rights to all conceivable key combinations. |
GavinWraith (26) 1563 posts |
I had not given any thought to this scenario. I hardly ever use keyboard shortcuts anyway, as my credo is to minimize keyboard-use. Is there a problem because the timescales involved in keyboard handling may be orders of magnitude larger than those involved in task-switching, or is that irrelevant? |
Paolo Fabio Zaino (28) 1882 posts |
Thanks Steve! another requirement to add to both the short cut request and the software to handle it as well! :) |
Paolo Fabio Zaino (28) 1882 posts |
@ Gavin
There are few issues actualy, so of which are the following: 1) There is no standardised API to request short cuts 2) There is no standard API to request a shot cut sequence that may be used to start up a specific task (for instance a desktop search) if an App is not loaded yet and doesn’t use trick above 3) A user has no way to control (and reconfigure) which short cuts are used by which Application. Plus, it would be much nicer to actually have an API for this, so Apps would not need to use trickery. So, the idea is to provide such an API through a TaskModule that runs without a UI, which intercept all key pressed, insted of Apps having to do that, and accept requests from Apps to send them back a message when such key sequence has been intercepted. This allows not only to have some degree of control of how short cuts are being delivered, but it also increase possibilities for developers, without having them to have to write more code. On top of that, it allow a user to create a short cut request file (an INI file or a JSON file format), where a user, without coding at all, can request a short cut to the Global SHort Cuts Handler and ask it to perform a specific action when such short cut is intercepted. For example lunch a program or execute a command etc. One of the goals of my DME project is to provide facilities for developers to be able to deliver more features (where possible) without havign to write more code. Given that one of the thing that most people (m eincluded) have reported is the lack of available time to write code for RISC OS. One way to help solving this is to create infrastructure that requires a developer to have to write less code (which is why I am doing all this fo rmyself first and sharing with everyone else interested). Hope this answer your question. |
Steve Pampling (1551) 8170 posts |
That’s the bit where you start finding the interception of keypresses by filer, wimp (been a while since I played with that stuff) in a bit of a fairground rollercoaster twist and turn. Part of the fun will be doing it in a way that ignores what the UK keycaps say so that you can insert modifications to allow shortcuts to drop onto meaningful letters in a different layout (maybe) Just thinking that it was suggested that key shortcuts were something that some people shun/avoid, but then there are people that struggle with small portables when they also have to carry around a mouse. Or a tweaked version of RPCEmu where that works and menu, sh-menu and ctrl-menu represent different mouse keys. (That requires a small tweak of the RPCEmu source – nothing big) |
Steve Pampling (1551) 8170 posts |
If you’re referring to desktop (wimp/filer) keyboard shortcuts, then as I said above in many cases the (assembler) code is there already, you just hook onto it. A small section of the “keypress” source for Filer shows that by adding two lines you can make F5 refresh the screen – just like on Windows or Linux and RO4.3x/6
Edit I forgot, the messages file needs a small edit to add the shortcut reminder to the normal menus for each of the new shortcuts |
Paolo Fabio Zaino (28) 1882 posts |
Indeed, but that is a problem for “another day”. In the sense that first we should define a good and extensible API that works with Apps and Tools, then we can workout fixes for the Filer which obviously handles shotcuts 80s style still. If we “don’t do, nothing will change”. I am sure ROOL is going to be interested in a better approach that hold compatibility with the past. |
GavinWraith (26) 1563 posts |
Thanks for the explanations, Paolo. |
Steffen Huber (91) 1953 posts |
The idea of using CFront as some kind of “C with objects” preprocessor certainly has merits. Thinking about rewriting Assembler in C is – now that we have reached the second decade of the 21st century – quite insane in my view. C adds very little abstraction, and you still have millions of pitfalls to avoid, especially if you want your code to end up portable to different CPUs. The only advantage of C is that we already have a compiler, and it looks like everybody insists that the DDE should be used now and forever for all things RISC OS. So CFront is certainly an option to consider, because it adds so much time-saving and error-avoiding abstraction to plain C. But you could also ask – why not use Vala instead, if you are in love with dead-ends. Personally, I would suggest “port LLVM and use Rust instead”. A working LLVM infrastructure would open up a large amount of tooling that RISC OS software development is sorely lacking, and using Rust for the core OS would have many many benefits, not only on the abstraction-and-features level. Like using a language that is now also used in large open source projects like the Linux kernel and Firefox, so there is a certain amount of familiarity in the coder market. Nobody will be attracted by “it looks a bit like C++, but the 1995 limited version of it”. But maybe nobody is attracted to RISC OS development anyway, so this might be a moot point, and you’d better invest in a CFront-like transpiler that uses BBC BASIC as input. The problem with any kind of up-to-date compiler tooling from the open source world (read: GCC and LLVM) is of course that the ARM backends no longer support ARMv2/3/4, which might be a problem for targeting RPCemu and the old native hardware. But my wild guess would be that maintaining an ARM backend is a lot less work than continuing maintenance of the DDE wrt new C standards and the like. But since I am not going to do the work anyway, I shut up now. Give me a shout when I can use Java for RISC OS development (or maybe I should really try myself to get Jainja working?). |
David J. Ruck (33) 1635 posts |
Steffen, I agree that asm to C is not going far enough, it’s out of the fire and in to the frying pan. Moving to a language which allows RAII* is the very minimum, and more specifically something that lets you deal with strings as an object type, and not buffer manipulation hell as in C. *RAII stands for Resource Allocation Is Initialisation, but what it actually means that anything that requires to memory to be dynamically allocated is some form of object with a defined lifetime, that automatically allocates it when created and releases it when destroyed. In C++ that means your object is a class where the constructor allocates the memory and the destructor frees it, so you can create an instance of it just the same as a simple type like an int or a float and when it goes out of scope it frees the memory used without the user having to worry about it. Paolo’s suggestion of using CFront does actually meet my criteria (just), and could be used for people moving up directly from plain C. Unfortunately it can’t be used by anyone with recent experience of C++, as it involves unlearning everything they’ve become familiar with in the language and class libraries in the last 35 years, including all the C++11 and later stuff which has finally made the language tolerable again. If I could choose any language except Python (as only Gerph is allowed to write operating systems in that) it would be C#/mono which has a very clean syntax and is what C++ and the Standard Template Library should have been if hadn’t started off by being badly hacked on top of C (that’s you CFront), and whilst inspired by Java doesn’t have many of the restrictions that drive C programmers insane. One thing often stated as a disadvantage performance wise is not being compiled to native code, but using an intermediate form which is just in time compiled by the runtime, however that would be very useful in the transition from 32 to 64 bit ARM, eliminating the need for any recompilation. But it doesn’t look like anyone will ever drag the vast bulk of the runtime and framework over to RISC OS though. As for Rust, I think there is a lot of wishful thinking over code quality. It can eliminate one class of memory errors by making it far more difficult to code, but it does little for any other types of problems. And just like with managed memory languages, where there is an enviable interface with external code (as there will be until the last shred of C, C++ or assembler is eliminated), the boundary has to be marked as unsafe and breaks the memory safety guarantees. |
Rick Murray (539) 13840 posts |
Java? Java?! What with Oracle’s shenanigans, the wise are moving on from Java.
It exists and it works with the RISC OS way of doing things. All this discussion about alternatives is good and right (as, as has been noted, C might have been the answer fifty years ago but time moves on), however it’s all moot until the time a functional compiler exists. That being said, there’s roughly zero chance that a future RISC OS will be API compatible with the current one, so maybe we need an entirely new language to go with the new OS, and all the assembler/BASIC/C stuff can remain as parts of “legacy RISC OS”. |
David Gee (1833) 268 posts |
There are other Java’s than Oracle’s. Though in the main area where Java is used for app development — Android — it is being supplanted by Kotlin. Rust may be being used increasingly in Linux, but it is not a language, AFAIK, that people like to code in. It’s also a very complex language to learn, so not that many people know it and the number of such people who would like to use it in their spare time on RISC OS development is probably tiny. Most current OSs are written in C, including Mac OS and Windows — even if other languages (C#, Swift) are preferred for app development. Exceptions are BeOS/Haiku (C++) and the earlier versions of pre-OS X Mac OS (Object Pascal—though I believe later versions changed to C). Of course Acorn originally intended their OS to be written in Modula-2 (it’s strange now to remember that M2 was once considered a clear rival to C). If Acorn had survived I reckon they’d have done what Apple did — produced a Unix-based OS with a RISC OS-lookalike GUI on top and and a way of running old apps effectively in an Aemulor like manner. There will probably never be a version of RISC OS with no API compatibility — what would be the point? There would be no applications to run on it… |
Paolo Fabio Zaino (28) 1882 posts |
Few psudo-technical notes ASM vs C vs C++ vs Rust We all agree that ASM belong to the past (good!). It’s nice to see people knowing that an implementation in C will take a long time (not just because there aren’t many developers around, but because there will be many mistakes done and a ton of bugs that will need squiscing before it’s even testable by the community).
While the real C++ offers a lot more good features than CFront, it relies on the C++ STDLib, which is the main reason why C++ failed (when people tried to use it with Linux) and never made it into the Windows Kernel either (yup, you still CAN’t write Windows drivers in C++ at least till Windows 10 IIRC). However, there are experiments and some OS is written with a combination of C++ and C that actually works, C++OS, Haiku and few others, however they all require some ASM based tweaking. For instance, a boot loader generally doesn’t set stack and calls main function, so this requires an extra OS loader that does the job. Another important part is that the C++ kernel needs to be written within – extern “C” {} – tags, to avoid the compiler to mangle the function (which is why I mentioned it’s a combination of C++ and C). There are some other little bits here and there, but you get the idea: it’s not straight forward :) CFront, on the other hand, doesn’t have these problems (except the mangling, which is part of C++ since the very beginning) and besides, I specifically mentioned it only for the WIMP infrastructure, not the kernel. In such a scenario, it will most likely deliver a much more maintainable WIMP than it is now, 300% warranted and a relatively shorter development time than using plain C. This because CFront supports RAII and other C++ features which will help speed up development time and reduce bugs for the WIMP functionalities. It won’t help on the WIMP API, which (most likely) will still need a proxy layer written in ASM (TBD).
To rewrite RISC OS anew, we do not need necessarily DDE, any compiler that can target the required hardware, that can build without the need for a core and STD library and that produces binary code (aka no byte-code and alike) will do. (Read full stop) As Rick has mentioned, the real challenge will be replicating the original RISC OS API, that, most likely won’t work with anything but C and Rust (and a lot of work added and still in ASM). And the result of this may still not work! Even if done spot on right. This is because the old API has a set of assumptions that, it’s clear, we do not wish to have on a new RISC OS (like a complete lack of security and possibility to exchange pointers between user-space and kernel and both happily accessing each-other memory like we were back in the 80s all over again!). BUT (yes, there is always a but), old applications can be executed within an emulation layer, so a new RISC OS without API compatibility with the old RISC OS will still be able to execute old code through an “RISCOSulator” of some form and sort. That will be needed ANYWAY to have some apps running on a 64bit system, so it’s a not avoidable step.
Rust CAN be used to produce a pure binary, no core, no STD, _start based kernel and can cooperate happily with ASM, I have done a lot of work already (in other shores) for this. It totally works fine with C as well (through unsafe {} tagged code areas) and has all the benefits of C++ plus more, but doesn’t solve ALL the problems, so, skills are still required (probably more than using C), but yes, it will produce more robust code from day 1. But make no mistake, Rust is NOT C. Rust is a modern low level language, aka a whole new beast. C for example is a programming language that takes a week to learn and a life to master. Rust, on the other hand, can have a really steep learning curve for many developers. In C, if the language doesn’t have a feature, we code more. In Rust (at least for now), most likely that feature will be added to the language (in a C++ fashion basically). However, it will be added, still maintaining an extremely small STD library, which means the implementation of such a feature might add even more complexity to the language (given the constraint of being a “C” without the C philosophy). Another issue here is that, Rust, like modern C++, does NOT target old ARM architectures. So, writing an OS in Rust, means finally cutting strings with the past. But is this such a bad thing? I mean, if someone writes an OS that is reliable, robust, easy to program on, secure and that is easy to use like RISC OS was, would this really be a problem when you can still run all your old Apps on the aforementioned “RISCOSulator”? I don’t this so, except some developer my understandably argue: 2 complete different APIs are way too much work for me to just code for RISC OS half an hour on a Sunday evening! And that is where everything falls to pieces. At this point, I go to make a coffee (Rick will, most likely, protest about it XD), I’ll fire up my DDE and write some code, and will forget about this entire discussion until the next time we’ll make it again.
There are alternatives, but porting this stuff on RISC OS has problems: All modern code has assumptions. One of them is preemptive multi-tasking <—— Take the “port” of SQLLite to RISC OS (for example). Is it really a full port to RISC OS or is it just a set of patches to make it build and run on RISC OS? In other words: If you use SQLite with few records, you may be fooled that everything is ok, if, instead, you use it with a lot of data and make a search from a desktop App then your desktop will freeze during the search. This is not Mahoney’s fault, it’s that SQLite assumes it’s being executed on a preemptive scheduler and with an OS that has file caching. RISC OS ain’t that OS and so the issue arise. IMHO, a proper port to RISC OS is a piece of code that embraces all the assumptions RISC OS has. So, in the case of Java, that means that the JVM should be equipped with a byte-code scheduler that every so often should return control to the OS and intercept all the events for the application being executed on the JVM and then pass those as swing events etc. Not just interpret java byte-code and be done with it. The same for Mono. And let’s not even mention their jitters.
These are features you do not want to have to deal with when you are writing an OS, believe me, they are a total pain to deal with at such low level. Emulation Emulators are the “easy” path. Reuse an existing and well tested OS, put RPCemu on it and your RISC OS. This will live longer than probably most of us will. HW and OS Emulation Everything said above, would be completely different if such an OS would be written in a form of Emulation that intercepts calls and act as a proxy between the old RISC OS user world, the ancient kernel and a Host system. This is the land where Pyromaniac lives, and it’s a great approach that has a lot of useful features, if one doesn’t need uber-high performances. Virtualization This ain’t gonna reduce complexity, quite the opposite. But it can help abstracting an underlining HW platform to reduce the work done on guest OS like RISC OS would be. For a 64 bit scenario, the Hypervisor will require a binary translator library that processes the thread attributed to the guest OS and translate (look-head) a chunk of code. Here, we enter another dimension of complexity, for instance, are we translating the right chunk of code or will there be a jump and so throw away that code and translate something else? (It’s an example of problems in this particular environment, there is more). HTH P.S. If anything I have mentioned above may sound against what you wish/desire/like or may come out too short that would sound rude in British English, I did not mean to be rude. Remember I am not British. |