4 ms·
Real low-level assembly language probably is easier to really understand and reason about than C++, isn't it? I used to code in C++ with Borland C++ Builder an
by qwerty456127 4y ago
Real low-level assembly language probably is easier to really understand and reason about than C++, isn't it?
I used to code in C++ with Borland C++ Builder and it felt almost the same like doing WinForms with C# pracrtically but once you want to really understand the language and what's going on the deeper level C++ seems infinitely obscure.
- nuancebydefault 4y agoCode written in the standard of C++ of 20 years ago (pre-c++11) does not even remotely look anymore like today's code conforming c++17. (let alone 20 or 23). Understanding it only got harder over time.
- FpUser 4y agoStd lib level code for sure. Application level is easy to grasp if written by decent programmer.
- badpun 4y agoHowever, Application code is calling all these nightmarish library functions which you don’t understand and have to rely heavily on documentation and experimentation to use. It’s not like that at all in e.g. Java, where reading the standard library code is a pleasant and educating practice.
- account42 4y agoThis is good because unlike Java, for C++ there are several standard library implementations so relying on something that happens to be guaranteed by one is not a good idea. The standard and documentation is the only place where you will find what is actually guaranteed to work.
- FpUser 4y agoPlease stop this FUD. I have zero trouble using std::whatever in C++ without diving into their code. Usage is very well though out and user friendly. Higher level libraries do use templates on a different level and are very readable.
- AnimalMuppet 4y ago> Real low-level assembly language probably is easier to really understand and reason about than C++, isn't it? No. There's no comparison. Assembly is far harder. Assembly can be completely unstructured. It can jump into the middle of a subroutine. OS permitting, it can be self-modifying. You have to have a very clear understanding of how each instruction can affect the condition flags. Instead of getting very familiar with the C++ spec, you're getting very familiar with the chip spec. You can write clean, understandable assembler. To do so, you have to have self-discipline. You have to resist using all the things that the assembler makes possible. But you can do that in C++, too - and should.
- tialaramex 4y agoIt's hard to judge. They're both potentially too complicated to understand, and in different ways. I think we probably have to give it to assembly as easier though. There's no IFNDR in assembly. (Ill-Formed No Diagnostic Required: the C++ get out which says well, this isn't a C++ program and so it has no defined meaning but your compiler probably won't even warn you about that, so your code does compile it just has no defined behaviour)
- pwdisswordfishc 4y agoThere is. It's called "undefined opcode".
- tialaramex 4y agoUndefined Opcodes are just like C++ UB. They're very bad news, but they're nothing compared to how terrible IFNDR is. I think C++ programmers either don't realise how bad IFNDR is, or they just don't want to think about it. IFNDR means your entire program is always meaningless. Let's take a UB example, an IFNDR example, and an undefined Opcode example and compare the potential consequences 1. UB example. We have a program which does some work in a loop, the user can select how many times between 0 and 256 the loop should execute. Unfortunately this should have been limited to 255 times, if the user picks 256 the loop exit condition is always false. In C++ this is Undefined Behaviour and the program's behaviour is arbitrary once that arises. So long as you never select 256 in the loop iteration setting, this program is fine. 2. IFNDR example. This program only lets the user select between 0 to 200 iterations. Unfortunately if more than 10 iterations are used the arithetic inside the loop uses a std::vector of floating point values with an algorithm specifying that the values are std::totally_ordered, as a result this is IFNDR because floating point values are a structural match, so this compiles, but they aren't a semantic match for the total order concept and that's IFNDR. Even if the feature is never activated and nothing is ever processed with the std::totally_ordered algorithm, the behaviour of the entire program is undefined, the program has no meaning at all. Running this program at all could cause anything to happen. 3. Undefined Opcode. This time the program has between 1 and 100 iterations, it's written in assembly but unfortunately due to an oversight for the odd numbers of iterations the undefined Opcode GLARK R0,R0 is executed which only works on a model of CPU which you don't have. This program misbehaves, perhaps spontaneously rebooting or showing other bizarre behaviour - but only if that Opcode is executed, which for even numbers of iterations never happens. So long as you only use even numbers of iterations, this program is fine.
- jsrcout 4y ago> Real low-level assembly language probably is easier to really understand and reason about than C++, isn't it? I've often thought that. If nothing else, if a given opcode (say, an ADD) is being used, things like integer wraparound are going to do something specific and well defined, not cause undefined behavior and invalidate the entire execution of your program. I miss that from my 6502 assembly programming days :-).