C would probably not have survived unless it had this flexibility.
But its not justa historical thing. Today there are modern platforms like DSPs that have 32bit sized char, because that is the smallest addressable type. These platforms depend on C for tool chains, even if most "portable" C wont run correctly on them. The fact that you can build hardware like that, and not have to invent a new language / dialect to program them is a huge win for the world.
<edit> I didnt see the footnote about DSPs at first read </edit>
I don't agree. UNIX was an extremely niche operating system until Linux won the data center, at that time both C and C++ were already extremely popular outside the UNIX world. C won because it was so easy to adapt to new hardware architectures (even GPU shading languages are just minimally extended flavours of C and C++).
That's way way later. UNIXes were the ones running in 70s and 80s. WindowsNT and Linux only later came to take a slice and, still later on, Linux won the day. How anyone would consider UNIX "niche" is beyond me.
IBM mainframes added a UNIX subsystem in the 1990s, starting with UNIX for MVS, nowadays z/OS UNIX.
DEC's VAX/VMS became Open VMS when UNIX/POSIX support was added in the early 1990's as well.
Other mainframe systems added similar POSIX environments.
The way Windows NT OS linage works isn't something novel, it is how mainframes have introduced multiple OS personalities and virtualisation modes since the late 70's.
There is a weird moment toward the end of the 1990s when Microsoft is trying to show their NT is a serious competitor in this space.
Traditionally this was a profitable niche, Microsoft would like to take a fat piece of that, and instead what happened is that Linux destroyed the profit margin. A million dollars overhead that would have kept a hungry UNIX® vendor alive on your project didn't turn into an extra million dollars on Microsoft's balance sheet, instead it evaporated because Linux is "free". And so then Microsoft lost interest.
Yeah, and one of the ways to show it was a serious OS for DoD projects was to have a POSIX subsystem, which had they kept it around, Linux would never have taken off on the PC, and there would be no need for WSL 40 years later.
The POSIX subsystem is a box checking exercise. The reason the box was there isn't satisfied but the box was checked and Microsoft hoped that's good enough. If you need "a Unix" and they give you NT and circle the stuff about POSIX you don't go "Oh, perfect" you ask them to fix the requirements document so that you can have an actual Unix next time.
WSL is Redmond going OK yeah, here you go, an actual Unix.
It was a requirement on government contract tenders. If you didn't support POSIX, you didn't get the contract and the government would have continued using SunOS or AIX or something instead of Windows NT. Remember that POSIX was designed to make these OSes somewhat interchangeable - they wouldn't order something they knew was incompatible with everything they already had.
Most people only cared about C, because they needed to work on UNIX, and UNIX was taking over the server room and all 1980's graphical workstations.
C was pretty much ignored on 8 bit home computers, outside some toy compilers for CP/M.
In the 16 bit days, it was yet another language alongside BASIC compilers, Pascal, Modula-2, Assembly.
C is so tied to UNIX, that POSIX had to be created so that any non-UNIX operating system could provide a cozy home for their C compilers.
UNIX/POSIX is for all practical purposes the runtime most C applications rely on, there are naturally some exceptions like free-standing or Windows (which eventually gave up and add to start improving its support).
It is only due to historical accident that Microsoft gave up on Xenix, instead of replacing their MS-DOS efforts.
I don't know about you but I need zero POSIX to write C on Windows. Not even much of the (mostly bad) C standard library. I use snprintf for convenience (but I don't have to), and memcpy, that's about it.
And many projects properly abstract their OS layer so they aren't tied to POSIX.
Maybe Unix is tied to C, but C isn't tied to Unix.
> UNIX/POSIX is for all practical purposes the runtime most C applications rely on, there are naturally some exceptions like free-standing or Windows (which eventually gave up and add to start improving its support).
Point is that C isn't tied to POSIX. It's just not. Of course there are apps created on e.g. Linux, those sometimes get ported by relying on standardized "POSIX" platform. But that's not how you have to program, and it isn't a great way to program. And it isn't a sufficient platform to do anything useful.
Disclaimer: This is just some cursory research using LLMs.
C was invented to rewrite UNIX in a programming language that made it easy to port UNIX between machines.
So what you're saying is contradictory. You're saying the underlying motivation of C was wrong or unnecessary (porting UNIX to different hardware architectures) but C won because that underlying motivation (easy porting between hardware architectures) was partially right.
Your position is now that C didn't need UNIX as a stopgap, which is weird because your argument gains no weight (basically saying C's dominance is sheer coincidence) if it's true but if it's false you're just plain wrong.
My point is that C's popularity quickly outgrew the popularity of UNIX, especially during most of the 1990s before Linux made UNIX accessible to us "PC peasants". Most 1990s PC games were written in C, and C was also the dominant high level language on 16/32 bitters like the Amiga or Atari ST.
(and note how I specifically wrote "dominant high level language", not "dominant language", since assembly coding was indeed very relevant on those machines, for UI apps 100% assembly was quite rare though, and hybrid C/ASM seems to have been more common).
It depends: for the classic 8 bit home computers, games were mostly written in assembly. Later DOS games were commonly either written in Pascal or C, but quite a bit off Assembler code was often used for the more performance-critical code sections.
of course typically contained a lot more C/Pascal code than games that were more on the "multimedia demo" side with a simpler game logic.
I have had the suspicion for a while now, that any attempted discussions about the merits of C's design that try to connect this to its success, are missing a massive part of the picture if they don't mention UNIX.
We don't make this mistake about JavaScript; nobody tries to argue that the confusing semantics of the "var" keyword or the "==" operator somehow were actually instrumental to its success. It's obvious that JavaScript won because it was what was on the web. Maybe C is not much different.
It isn't, most languages win because of a platform that comes with them, or a product, no language has ever won on their own, plain grammar, semantics and standard library without anything else.
JavaScript and Web, UNIX and C, UNIX/Windows/Mac OS/OS/2 and C++, Ruby and Rails, Zope and Python, Tcl and AOLServer/Vignette, Windows and VB, 8 bit computer ROMs and BASIC, and so on.
This kind of flexibility is a purely historical thing.
On modern computers, it is impossible to write correct C programs that are agnostic about the true size in bits of the "flexible" types char, short, int, long and long long.
If your program must depend on assumptions about the size in bits of the integer types, those assumptions must be made explicit, by using types like int16_t, int32_t etc.
Writing correct programs that are agnostic about the integer sizes is possible only in programming languages that allow the programmer to install an integer overflow handler even if the CPU does not generate a hardware exception for that, in which case the compiler must insert appropriate overflow checking instructions that would invoke the installed handler when necessary.
This problem did not exist on old computers, where there were hardware exceptions for integer overflows, so even in C you could install a signal handler for SIGFPE, which would also be invoked by integer overflows.
That's not true. All the basic types have minimum sizes, so its perfectly reasonable to write software that stays within those bounds. You can avoid any overflows if you know the minimum limits.
If you use the minimum sizes, your program will be very inefficient on most CPUs.
I have never considered that this is an acceptable solution, which is why in decades of using C, during which I had many times to port programs or even entire real-time operating systems between different ISAs, I have never used those minimum sizes.
Instead of having those minimum sizes, which I consider useless, C should have had since the beginning, besides sizeof, which gives the size ratio between another type and char, another operator or macro to provide the size in bits of any integer type.
With that, it would have been possible to use types like short, int or long in a portable way.
Nowadays, there are _WIDTH, _MAX and _MIN constants for the integer types, but those have been added relatively late to the language, together with the integer types with specified width, for which those constants are superfluous.
The _MAX and _MIN, along with CHAR_BIT, was defined for C89 (the first standard for C) 37 years ago, so it was possible to choose the appropriate type. I recall using the C preprocessor to define fixed (or at least, minimum) types for needed values:
#include <limits.h>
#if INT_MIN == 32767 && INT_MIN >= 2147483647L
# error too small
#else
# error just right
#endif
It was C99 (27 years ago) where we got the fixed sized integers. So how do you define "relatively" here?
Not sure why you would need to invent an new programming language when we're still strictly talking about data types. You just introduce a new data type for the hardware if that's what's necessary. You don't need a whole language.
This is why I think so many C developers have no clue what they are doing. They just take whatever decision was made in C as gospel instead of thinking of everything being up for negotiation.
You probably never did embedded and small devices. They still rule the world. Most CPU's I work on are 8-bit or 16-bit still. avr-gcc is one of the most important compilers still, behind arm-gcc. Having 32 or 64 bits available is nice, but not granted. We spend <2€ on a typical CPU.
quelsolaar · · focus · HN ↗
C would probably not have survived unless it had this flexibility.
But its not justa historical thing. Today there are modern platforms like DSPs that have 32bit sized char, because that is the smallest addressable type. These platforms depend on C for tool chains, even if most "portable" C wont run correctly on them. The fact that you can build hardware like that, and not have to invent a new language / dialect to program them is a huge win for the world.
<edit> I didnt see the footnote about DSPs at first read </edit>
pjmlp · · focus · HN ↗
[deleted] · · focus · HN ↗
[deleted]
flohofwoe · · focus · HN ↗
prerok · · focus · HN ↗
fragmede · · focus · HN ↗
pjmlp · · focus · HN ↗
prerok · · focus · HN ↗
fragmede · · focus · HN ↗
pjmlp · · focus · HN ↗
DEC's VAX/VMS became Open VMS when UNIX/POSIX support was added in the early 1990's as well.
Other mainframe systems added similar POSIX environments.
The way Windows NT OS linage works isn't something novel, it is how mainframes have introduced multiple OS personalities and virtualisation modes since the late 70's.
tialaramex · · focus · HN ↗
Traditionally this was a profitable niche, Microsoft would like to take a fat piece of that, and instead what happened is that Linux destroyed the profit margin. A million dollars overhead that would have kept a hungry UNIX® vendor alive on your project didn't turn into an extra million dollars on Microsoft's balance sheet, instead it evaporated because Linux is "free". And so then Microsoft lost interest.
pjmlp · · focus · HN ↗
tialaramex · · focus · HN ↗
WSL is Redmond going OK yeah, here you go, an actual Unix.
pjmlp · · focus · HN ↗
The point still stands, that POSIX checkbox was relevant enough for spending the money in engineers salary during Windows NT 3.51 development.
someonebaggy · · focus · HN ↗
pjmlp · · focus · HN ↗
For those that don't read standards, POSIX certification requires the existence of a C compiler, the more recent one being C17 compliant.
<a href="https://pubs.opengroup.org/onlinepubs/9799919799/utilities/c17.html" rel="nofollow">https://pubs.opengroup.org/onlinepubs/9799919799/utilities/c...
iberator · · focus · HN ↗
pjmlp · · focus · HN ↗
C was pretty much ignored on 8 bit home computers, outside some toy compilers for CP/M.
In the 16 bit days, it was yet another language alongside BASIC compilers, Pascal, Modula-2, Assembly.
C is so tied to UNIX, that POSIX had to be created so that any non-UNIX operating system could provide a cozy home for their C compilers.
UNIX/POSIX is for all practical purposes the runtime most C applications rely on, there are naturally some exceptions like free-standing or Windows (which eventually gave up and add to start improving its support).
It is only due to historical accident that Microsoft gave up on Xenix, instead of replacing their MS-DOS efforts.
jstimpfle · · focus · HN ↗
And many projects properly abstract their OS layer so they aren't tied to POSIX.
Maybe Unix is tied to C, but C isn't tied to Unix.
pjmlp · · focus · HN ↗
> UNIX/POSIX is for all practical purposes the runtime most C applications rely on, there are naturally some exceptions like free-standing or Windows (which eventually gave up and add to start improving its support).
jstimpfle · · focus · HN ↗
imtringued · · focus · HN ↗
C was invented to rewrite UNIX in a programming language that made it easy to port UNIX between machines.
So what you're saying is contradictory. You're saying the underlying motivation of C was wrong or unnecessary (porting UNIX to different hardware architectures) but C won because that underlying motivation (easy porting between hardware architectures) was partially right.
Your position is now that C didn't need UNIX as a stopgap, which is weird because your argument gains no weight (basically saying C's dominance is sheer coincidence) if it's true but if it's false you're just plain wrong.
flohofwoe · · focus · HN ↗
pjmlp · · focus · HN ↗
On the consoles it took until PlayStation for C to take off among game devs.
Additionally many Amiga games used Blitz BASIC and AMOS.
Anyone involved in the Demoscene early days would be 100% Assembly as well.
On PC, it required until Watcom with its great MS-DOS extender for devs to finally move away from Assembly in mass.
flohofwoe · · focus · HN ↗
I was there, Gandalf ;)
(and note how I specifically wrote "dominant high level language", not "dominant language", since assembly coding was indeed very relevant on those machines, for UI apps 100% assembly was quite rare though, and hybrid C/ASM seems to have been more common).
pjmlp · · focus · HN ↗
In my part of the Iberian Penisula it was Turbo Pascal on PC and AMOS/Blitz Basic on Amiga.
With lots of inline Assembly anyway.
jstimpfle · · focus · HN ↗
pjmlp · · focus · HN ↗
aleph_minus_one · · focus · HN ↗
It depends: for the classic 8 bit home computers, games were mostly written in assembly. Later DOS games were commonly either written in Pascal or C, but quite a bit off Assembler code was often used for the more performance-critical code sections.
pjmlp · · focus · HN ↗
I have seen code where folks used Pascal or C compilers as poor man's macro assemblers, the "quite a bit" was rather large.
aleph_minus_one · · focus · HN ↗
Games that had quite a bit of code that profited from the higher-level abstractions that C/Pascal provided, such as
- resource management (including dynamic asset loading/unloading)
- enemy AI
- pathfinding
- ...
of course typically contained a lot more C/Pascal code than games that were more on the "multimedia demo" side with a simpler game logic.
jjav · · focus · HN ↗
UNIX was ubiquitous in the data center well before Linus even posted his first version of Linux on USENET.
Everything ran on SunOS, HP-UX, IRIX, AIX, etc.
ykonstant · · focus · HN ↗
?!? What a claim!
i2talics · · focus · HN ↗
We don't make this mistake about JavaScript; nobody tries to argue that the confusing semantics of the "var" keyword or the "==" operator somehow were actually instrumental to its success. It's obvious that JavaScript won because it was what was on the web. Maybe C is not much different.
pjmlp · · focus · HN ↗
JavaScript and Web, UNIX and C, UNIX/Windows/Mac OS/OS/2 and C++, Ruby and Rails, Zope and Python, Tcl and AOLServer/Vignette, Windows and VB, 8 bit computer ROMs and BASIC, and so on.
adrian_b · · focus · HN ↗
On modern computers, it is impossible to write correct C programs that are agnostic about the true size in bits of the "flexible" types char, short, int, long and long long.
If your program must depend on assumptions about the size in bits of the integer types, those assumptions must be made explicit, by using types like int16_t, int32_t etc.
Writing correct programs that are agnostic about the integer sizes is possible only in programming languages that allow the programmer to install an integer overflow handler even if the CPU does not generate a hardware exception for that, in which case the compiler must insert appropriate overflow checking instructions that would invoke the installed handler when necessary.
This problem did not exist on old computers, where there were hardware exceptions for integer overflows, so even in C you could install a signal handler for SIGFPE, which would also be invoked by integer overflows.
quelsolaar · · focus · HN ↗
adrian_b · · focus · HN ↗
I have never considered that this is an acceptable solution, which is why in decades of using C, during which I had many times to port programs or even entire real-time operating systems between different ISAs, I have never used those minimum sizes.
Instead of having those minimum sizes, which I consider useless, C should have had since the beginning, besides sizeof, which gives the size ratio between another type and char, another operator or macro to provide the size in bits of any integer type.
With that, it would have been possible to use types like short, int or long in a portable way.
Nowadays, there are _WIDTH, _MAX and _MIN constants for the integer types, but those have been added relatively late to the language, together with the integer types with specified width, for which those constants are superfluous.
spc476 · · focus · HN ↗
someonebaggy · · focus · HN ↗
[deleted] · · focus · HN ↗
[deleted]
imtringued · · focus · HN ↗
This is why I think so many C developers have no clue what they are doing. They just take whatever decision was made in C as gospel instead of thinking of everything being up for negotiation.
rurban · · focus · HN ↗