4 ms·
Pretty much all of my career has been in maintenance, so I tend to see the mess that gets made and while bad-design is always a killer, I notice there are langu
by OneWingedShark 6y ago
Pretty much all of my career has been in maintenance, so I tend to see the mess that gets made and while bad-design is always a killer, I notice there are languages that encourage/discourage it to varying degrees.
In the case of C, and other C-like languages, I most recently have four or five custom-made programs [some requiring specialized tools] that have little/nothing in the way of documentation: what it does, the "why-for"/motivation, any sort of high-level architecture-plan, or design-documents.
Fortunately for me, most of the programs actually do have documentation thanks to a true hero that left before I arrived.
- icedchai 6y agoI did some maintenance work on a fairly large C++ system that called into a custom lower level library written in C. Much of my work involved extending that lower level library. It processed several billion dollars a year in financial transactions, and was barely documented at all. It was intended to be "portable" so it had bizarre #ifdefs all over the place in case you happened to compile it on an ancient Unix with a K&R compiler from 1986. This was the early 2000's, so nobody ever did that. I doubt it would've worked, yet those #ifdefs remained "just in case." The lower level C library was pretty clever. The original developer of most of it left about a year into my tenure there. He was one of the smartest guys I ever worked with. The C++ "app" layer was a different story. The worst part it was a 3000 line switch/case block with about 100 different cases, chock full of copy-and-pasted code. It went on... and on... and on... I still have nightmares about it.
- OneWingedShark 6y ago> The C++ "app" layer was a different story. The worst part it was a 3000 line switch/case block with about 100 different cases, chock full of copy-and-pasted code. It went on... and on... and on... I still have nightmares about it. Ouch. That sounds brutal. If I had to do something similar, or maintain that, in Ada I'd leverage nested subprograms, local type/subtype definitions, and mandatory case-coverage — and I've done similar with VMs, particular opcodes — so you get something like: Type Opcode is ( NOP, Add_A, SUB_A, ..., Rem_D ); Procedure Execute_Instruction( State : in out Machine_State; Instructions : in Instruction_Stream ) is Subtype A_Series is Opcode range Add_A..Sub_A; Subtype B_Series is Opcode range Add_B..Sub_B; Subtype C_Series is Opcode range Add_C..Sub_C; Subtype D_Series is Opcode range Add_D..Sub_D; Procedure Do_Add_A; -- other subprograms. Current : Opcode renames Decode( Next_Token( Instructions ) ); --... Begin Case Current is when A_Series => case A_Series'(Current) is when Add_A => Do_Add_A; end case; -- other series. end case; End Execute_Instruction; Of course you could structure it so that all the Do_OPCODE subprograms are local to the top-level switch, or local to the nested switches, as best suits the design; or decompose along 'families' of operation (Add_A, Add_B, Add_C, Add_D), but the important thing there is keeping things local/nested for maintainability.