Stop Teaching C
github.com
github.com
There is no portable computing without wrestling with ISA's. There is no using collections of Assembly in a reasonably articulable manner without C, there is no C++ without C, so on, and so forth.
The Art and Tao of Programming is to transcend the specifics of any layer of abstraction and flow as water does from the highest peaks to the oceans, getting stuff done along the way. A river without a way to the sea, while technically still making it to the ocean by groundwater percolation an evaporation, as a result of it's lack of connection has to journey much further, and much slower for having the state of affairs.
It might be a good idea not to teach C initially, or not much.
But you can't even write a hosted C++ program without touching the C-like subset: the main function and its argument handling reek of C.
C++ contains and is built-around a C dialect. Those who don't know the dialect do not know C++; they cannot understand and maintain C++ programs which use it.
Start teaching Pascal!
And we shouldn't call a pointer to an array of char a string, because it's not a string.
"A string is a contiguous sequence of characters terminated by and including the first null character."
later in the paragraph:
"A pointer to a string is a pointer to its initial (lowest addressed) character."
The italics indicate that a normative definition is being given. So, the official C terminology is that a pointer to a null-terminated char array is a "pointer to a string".
We really shouldn't.
And last I checked, Pascal has both PChar and PByte. Much better than C where both are called *char.
It implements a very simple metaphor for a computer. One that's useful for teaching how a computer works.
For more complicated things the mismatch starts to show. Maybe, at that point, it'd be time to teach other languages that can build upon the understanding of how a simple computer works.
> And last I checked, Pascal has both PChar and PByte. Much better than C where both are called *char.
The computer doesn't know the difference between a byte and a char. Usually, it doesn't even know what a char is.
That we have to do crap like `for(i=0;i<n;i++)` just to iterate an array, or this kind of insanity
https://docs.microsoft.com/en-us/cpp/c-runtime-library/refer...
to handle strings is nuts.
Having to state your solution in such primitive terms is throwing away information--the kind that an ever-so-slightly-improved compiler could use to great effect.
Not sure I follow. The hardware would have to know a lot about how your arrays are organized and how they'd map (or not) to your SIMD instructions. The compiler, at this level, is generating instructions that are no longer very close to the code you wrote.
For languages of a lower semantic level (just a wrapper over loads, stores, and arithmetic), making a compiler that can figure out whether the source is a good candidate for a particular hardware feature can be an intractable problem.
The computer may not know the difference, but having a way to let the compiler distinguish between the two opens up so many avenues for compile-time checks, smoother migration paths (i.e. ASCII/UTF-16/UTF-8), and better optimizations.
But then you are using the language to teach the language. I think C is most valuable to teach how a simple computer works as a foundation for exploring what more interesting computers could do and how we could program them (at this point, probably in languages that better match the abstraction you want).
I would rather not inflict that brain damage upon the children. If any of them want to start writing drivers, I'm sure they will take to pointer arithmetic like ducks to water--with or without C.
BTW, I think it'd be useful to teach assembly of a nice processor (NOT the x86, in any of its incarnations), with some toolbox of useful routines (at least for character output so the student can see something) before one goes into C.
And, it may be all I can get. I probably can't get a Pascal for that situation. I am somewhat unlikely to be able to get a Rust or an Ada. But I can probably get a C.
Especially in embedded systems, you can quite often get a C on the quirky chips, but you can't get anything else.
And no, all those machines are not "roughly a VAX of the same generation".
Now, that may not be quite the same as your claim, because I'm not going to take my embedded application from an 8085 and drop it unchanged onto my 56-bit oddball. (On the other hand, my 8085 code probably isn't using int64 anyway.)
In fact, embedded applications are more non-portable than that, because they always depend on the hardware context, not just on the compiler. Still, you can grab significant functionality from a different machine, modify it sensibly for the new environment, and use it.
Pascal was usable in embedded systems. It was used, even. But compared to C, it was like picking your nose with boxing gloves on. No, in my world at least, you don't want a "slightly higher semantic level". C got it far closer to right than any of the others, even Pascal.
I did suggest that C could have learned a thing or two from them. A higher semantic level does not imply reduced performance. In many cases, a richer language can give the compiler more opportunities to optimize. Walter Bright's D is a good example of a slightly-higher semantic level that still generates speedy binaries.
And a slow Pascal of yesteryear doesn't exactly put the nail in the coffin. C has also had its share of lame compilers.
https://borlandpascal.fandom.com/wiki/String_operations
And I did a lot of low-level stuff in in too! It was a long time ago, but I don't recall it being any better or worse than C++ when it was pointer time.