The problem with doing something no one has ever done before is that you have nothing to compare your work with and measure your progress against.
Where you can, you will bend the logic of the machine to your will; where you can't, your logic will be reshaped by it.
“...[O]ne of the earliest [applications] of dither came in World War II. Airplane bombers used mechanical computers to perform navigation and bomb trajectory calculations. Curiously, these computers (boxes filled with hundreds of gears and cogs) performed more accurately when flying on board the aircraft, and less well on ground. Engineers realized that the vibration from the aircraft reduced the error from sticky moving parts. Instead of moving in short jerks, they moved more continuously. Small vibrating motors were built into the computers, and their vibration was called dither from the Middle English verb "didderen", meaning "to tremble." Today, when you tap a mechanical meter to increase its accuracy, you are applying dither, and modern dictionaries define dither as a highly nervous, confused, or agitated state. In minute quantities, dither successfully makes a digitization system a little more analog in the good sense of the word.”
— Ken Pohlmann, Principles of Digital Audio
— Ken Pohlmann, Principles of Digital Audio
This media is not supported in your browser
VIEW IN TELEGRAM
Frustum culling
Frustum culling
In a game, we want to smooth animations:
Smooth animation = a high, fixed FPS (frames per second)
The GPU, like any other processor, can only do a fixed amount of work in a fixed amount of time.
A fixed FPS = a fixed time to create a frame = a fixed work budget per frame = limited things the GPU has to draws for a frame
The GPU mainly does two jobs:
• Vertex shading: related to the 3D geometric description of objects in the scene
• Pixel shading: drawing the individual pixels on the frame
We also want high quality images:
Higher image quality = more pixel shading = less vertex shading
To decrease the amount of vertex shading the CPU, which decides what should be drawn and sends them to the GPU, should skip the things outside the view cone.
Because the display is a rectangle, that view cone is a four-sided pyramid that has its point cut off; this is called a "frustum" in geometry.
Frustum cull = have the CPU skip telling the GPU to draw things outside of the viewing frustum
To a very rough approximation, an outdoors scene with a 90-degree view cone sees 1/4 of the full 360 degrees, so if we compare what would happen if we draw the full scene to drawing
only within the view cone, we skip approximately 3/4 of the vertex shading work.
Because of the way the system works, no pixel shading would have been done for culled objects, only vertex shading. So culling saves vertex shader work but not pixel shader work.
Note that frustum culling is not loading or unloading anything from the main memory. The objects still have to be loaded (in RAM) for physics, AI, etc. to be applied to them; they are
just not rendered (not sent to the GPU).
Almost every game and animated clips uses frustum culling, because it is simple, cheap and effective. It is probably the single most ubiquitous optimization found in graphics.
Generally, graphics optimization is important because it frees up GPU time to render more things, with more details. There are many ways of saving work on the GPU, such as:
• Frustum culling: not trying to draw things that can't be seen because of the view cone
• Occlusion culling: not trying to draw things that can't be seen because they're behind other things
• Level of detail: skipping small geometric details when things are far enough away those details can't be made out anyway
• Simpler mathematical approximations to the equations governing how things reflect light
— Summary of Why Frustum Culling Matters, and Why It's Not Important by nothings on Github
In a game, we want to smooth animations:
Smooth animation = a high, fixed FPS (frames per second)
The GPU, like any other processor, can only do a fixed amount of work in a fixed amount of time.
A fixed FPS = a fixed time to create a frame = a fixed work budget per frame = limited things the GPU has to draws for a frame
The GPU mainly does two jobs:
• Vertex shading: related to the 3D geometric description of objects in the scene
• Pixel shading: drawing the individual pixels on the frame
We also want high quality images:
Higher image quality = more pixel shading = less vertex shading
To decrease the amount of vertex shading the CPU, which decides what should be drawn and sends them to the GPU, should skip the things outside the view cone.
Because the display is a rectangle, that view cone is a four-sided pyramid that has its point cut off; this is called a "frustum" in geometry.
Frustum cull = have the CPU skip telling the GPU to draw things outside of the viewing frustum
To a very rough approximation, an outdoors scene with a 90-degree view cone sees 1/4 of the full 360 degrees, so if we compare what would happen if we draw the full scene to drawing
only within the view cone, we skip approximately 3/4 of the vertex shading work.
Because of the way the system works, no pixel shading would have been done for culled objects, only vertex shading. So culling saves vertex shader work but not pixel shader work.
Note that frustum culling is not loading or unloading anything from the main memory. The objects still have to be loaded (in RAM) for physics, AI, etc. to be applied to them; they are
just not rendered (not sent to the GPU).
Almost every game and animated clips uses frustum culling, because it is simple, cheap and effective. It is probably the single most ubiquitous optimization found in graphics.
Generally, graphics optimization is important because it frees up GPU time to render more things, with more details. There are many ways of saving work on the GPU, such as:
• Frustum culling: not trying to draw things that can't be seen because of the view cone
• Occlusion culling: not trying to draw things that can't be seen because they're behind other things
• Level of detail: skipping small geometric details when things are far enough away those details can't be made out anyway
• Simpler mathematical approximations to the equations governing how things reflect light
— Summary of Why Frustum Culling Matters, and Why It's Not Important by nothings on Github
Memory
Any IC that stores data for immediate use, often meaning addressable semiconductor memory, i.e. ICs consisting of silicon-based MOSFETs. Semiconductor memory is organized into memory cells.
Memory cell
An IC that stores a bit, and keeps its value until it is set or reset. The memory cell is the building block of any computer memory.
Storage devices can be categorized in three ways:
1. Random versus sequential, based on access
2. Volatile versus non-volatile, based on volatility
3. Primary versus secondary, based on usage
Any IC that stores data for immediate use, often meaning addressable semiconductor memory, i.e. ICs consisting of silicon-based MOSFETs. Semiconductor memory is organized into memory cells.
Memory cell
An IC that stores a bit, and keeps its value until it is set or reset. The memory cell is the building block of any computer memory.
Storage devices can be categorized in three ways:
1. Random versus sequential, based on access
2. Volatile versus non-volatile, based on volatility
3. Primary versus secondary, based on usage
Random access versus sequential access
The processor can access a part of the memory either directly (randomly), allowing data to be read or written in approximately the same amount of time irrespective of its physical location;
or sequentially, where the time required to read or write varies significantly, due to mechanical limitations, depending on the physical location of the data on the medium.
RAM:
• DRAM
• SRAM
SAM:
• Magnetic memory devices, e.g. hard disk drives
• Optical discs
While SAM is read in sequence, arbitrary locations can still be accessed by "seeking" to the requested location. This operation, however, is often relatively inefficient.
The processor can access a part of the memory either directly (randomly), allowing data to be read or written in approximately the same amount of time irrespective of its physical location;
or sequentially, where the time required to read or write varies significantly, due to mechanical limitations, depending on the physical location of the data on the medium.
RAM:
• DRAM
• SRAM
SAM:
• Magnetic memory devices, e.g. hard disk drives
• Optical discs
While SAM is read in sequence, arbitrary locations can still be accessed by "seeking" to the requested location. This operation, however, is often relatively inefficient.
Volatile versus non-volatile
Volatility means the memory requires power to maintain its data.
Volatile:
• DRAM
• SRAM
Non-volatile:
• Any kind of ROM
• Flash memory
• Magnetic memory devices, e.g. hard disk drives
• Optical discs
Volatility means the memory requires power to maintain its data.
Volatile:
• DRAM
• SRAM
Non-volatile:
• Any kind of ROM
• Flash memory
• Magnetic memory devices, e.g. hard disk drives
• Optical discs
Primary versus secondary
Due to their higher density at lower cost compared to RAM, as well as resistance to wear and non-volatility, SAM are more suitable for secondary data storage.
Primary:
• DRAM for main memory
• SRAM for processor cache
Secondary:
• Magnetic SAM (e.g. hard disk drives and solid-state drives)
• Optical discs
Due to their higher density at lower cost compared to RAM, as well as resistance to wear and non-volatility, SAM are more suitable for secondary data storage.
Primary:
• DRAM for main memory
• SRAM for processor cache
Secondary:
• Magnetic SAM (e.g. hard disk drives and solid-state drives)
• Optical discs
DRAM versus SRAM
Their differences arise from the differences in their cell design:
• Dynamic RAM cell: one transistor and one capacitor
• Static RAM cell: one flip-flops (4 or 6 transistors)
DRAM cells have a capacitor, charging and discharging which can store a "1" or a "0" in the cell. However the charge in this capacitor slowly leaks away.
Power consumption:
DRAM cells slowly lose their data ⇒ they need to be regularly refreshed ⇒ DRAM requires a refresh circuit ⇒ DRAM has a more complicated circuitry than SRAM ⇒ SRAM is faster than DRAM ⇒ SRAM uses more power than DRAM when it is working
DRAM needs to be regularly refreshed ⇒ DRAM uses much more power than SRAM when it is idle
DRAM has more complicated circuitry than SRAM ⇒ DRAM is more complicated for interfacing and control and has more complicated timing requirements
Usage:
SRAM is faster than DRAM ⇒ SRAM is used where speed is more important than cost and size, such as the cache memory in a processor
DRAM cells are smaller ⇒ DRAM has more areal density ⇒ DRAM is cheaper per bit ⇒ DRAM is used for data or program code that a processor needs, commonly known as simply "RAM"
Their differences arise from the differences in their cell design:
• Dynamic RAM cell: one transistor and one capacitor
• Static RAM cell: one flip-flops (4 or 6 transistors)
DRAM cells have a capacitor, charging and discharging which can store a "1" or a "0" in the cell. However the charge in this capacitor slowly leaks away.
Power consumption:
DRAM cells slowly lose their data ⇒ they need to be regularly refreshed ⇒ DRAM requires a refresh circuit ⇒ DRAM has a more complicated circuitry than SRAM ⇒ SRAM is faster than DRAM ⇒ SRAM uses more power than DRAM when it is working
DRAM needs to be regularly refreshed ⇒ DRAM uses much more power than SRAM when it is idle
DRAM has more complicated circuitry than SRAM ⇒ DRAM is more complicated for interfacing and control and has more complicated timing requirements
Usage:
SRAM is faster than DRAM ⇒ SRAM is used where speed is more important than cost and size, such as the cache memory in a processor
DRAM cells are smaller ⇒ DRAM has more areal density ⇒ DRAM is cheaper per bit ⇒ DRAM is used for data or program code that a processor needs, commonly known as simply "RAM"
Sound chip
- is an IC (chip) designed to produce sound through either digital, analog or a combination of both circuitries. Sound chips have oscillators, envelope controllers, samplers, filters and amplifiers. They also have signal generators as their fundamental modules which produce basic geometrical waveforms with variable timbre and pitch.
During the late 20th century, sound chips were widely used in arcade game system boards, video game consoles, home computers, and PC sound cards.
Programmable sound generator (PSG)
- is a sound chip that mixes a few (usually two or three) basic waveforms (pulse, square, triangle, sawtooth, etc.) and one pseudo-random-noise generator into a complex waveform, then shapes its amplitude envelope using attack, decay, sustain, and release time periods, so that the resulting waveform mimics a certain kind of sound.
Chiptune
- also known as chip music or 8-bit music, is a style of synthesized electronic music made using the PSG, or other music which intentionally sounds similar to it. While it has been a mostly underground genre, chiptune has had periods of moderate popularity in the 1980s and 21st century, and has influenced the development of EDM.
- is an IC (chip) designed to produce sound through either digital, analog or a combination of both circuitries. Sound chips have oscillators, envelope controllers, samplers, filters and amplifiers. They also have signal generators as their fundamental modules which produce basic geometrical waveforms with variable timbre and pitch.
During the late 20th century, sound chips were widely used in arcade game system boards, video game consoles, home computers, and PC sound cards.
Programmable sound generator (PSG)
- is a sound chip that mixes a few (usually two or three) basic waveforms (pulse, square, triangle, sawtooth, etc.) and one pseudo-random-noise generator into a complex waveform, then shapes its amplitude envelope using attack, decay, sustain, and release time periods, so that the resulting waveform mimics a certain kind of sound.
Chiptune
- also known as chip music or 8-bit music, is a style of synthesized electronic music made using the PSG, or other music which intentionally sounds similar to it. While it has been a mostly underground genre, chiptune has had periods of moderate popularity in the 1980s and 21st century, and has influenced the development of EDM.
Creating Chiptune
“If you've ever listened to an 8-bit cover of a song, you'll know how evocative it is of some nebulous childhood memories. ... [Chiptune] is a wonderful way to inject life into songs regardless of genre. It's not really clear why these sounds are so pleasing to some of us, but there are certainly plenty of good uses for transforming a familiar song with 8-bit sounds.”
⚠️ reducing a track's quality to 8 bits ≠ achieving signature chiptune sound
An 8-bit sound file has a more discrete wavelength than a higher bit version of the same file meaning there's less information about the sound, resulting in a lower quality sound but not altering its timbre. Recreating PSG-generated chiptune sound is more complicated than just reformatting a file in 8 bits.
Converting audio to MIDI
• Find a MIDI version of your audio
• https://www.bearaudiotool.com/mp3-to-midi
• https://www.conversion-tool.com/audiotomidi
• http://www.intelliscore.net/download.html
⚠️ The best option is the first one because when converting audio to MIDI, the quality of the resulting MIDI file highly depends on the structure of the input music, and will probably end up being nothing like the source track.
Converting MIDI to Chiptune
Download and launch GXSCC. It emulates a Famicom (NES) or SCC sound chip to play MIDIs like chiptunes.
For now ignore the complex GUI, and drag and drop your MIDI into the app window. Click the "Authoring" button at the top of the window. This will convert your MIDI to WAV and save in the same directory as the original.
To convert your WAV back into MP3 or any other format, use Audacity.
— Summary of How To Convert MP3 to 8-Bit by Arch
“If you've ever listened to an 8-bit cover of a song, you'll know how evocative it is of some nebulous childhood memories. ... [Chiptune] is a wonderful way to inject life into songs regardless of genre. It's not really clear why these sounds are so pleasing to some of us, but there are certainly plenty of good uses for transforming a familiar song with 8-bit sounds.”
⚠️ reducing a track's quality to 8 bits ≠ achieving signature chiptune sound
An 8-bit sound file has a more discrete wavelength than a higher bit version of the same file meaning there's less information about the sound, resulting in a lower quality sound but not altering its timbre. Recreating PSG-generated chiptune sound is more complicated than just reformatting a file in 8 bits.
Converting audio to MIDI
• Find a MIDI version of your audio
• https://www.bearaudiotool.com/mp3-to-midi
• https://www.conversion-tool.com/audiotomidi
• http://www.intelliscore.net/download.html
⚠️ The best option is the first one because when converting audio to MIDI, the quality of the resulting MIDI file highly depends on the structure of the input music, and will probably end up being nothing like the source track.
Converting MIDI to Chiptune
Download and launch GXSCC. It emulates a Famicom (NES) or SCC sound chip to play MIDIs like chiptunes.
For now ignore the complex GUI, and drag and drop your MIDI into the app window. Click the "Authoring" button at the top of the window. This will convert your MIDI to WAV and save in the same directory as the original.
To convert your WAV back into MP3 or any other format, use Audacity.
— Summary of How To Convert MP3 to 8-Bit by Arch
The desires of an implementer: to achieve a reasonable compromise whilst minimizing time and memory complexity, yet maintaining memory hygiene, hinder those of a designer: to imagine wildly and free of limitations and worrying of performance.
As a good programmer, you should try to somehow keep both sides alive.
As a good programmer, you should try to somehow keep both sides alive.
Birth of C
Mid-1960s: Bell Labs, MIT and General Electric were jointly developing an experimental time-sharing OS called Multics which was written in #PL_I and assembly language.
Late-1960s: Though Multics featured many innovations, it also presented severe problems, which frustrated researchers at Bell Labs until they gradually withdrew from the project.
1969: A team led by Ken Thompson and Dennis Ritchie, who were among the last to leave, decided to re-implement their experiences in a new, smaller project. They implemented a hierarchical file system, the concept of processes and device files, a command-line interpreter, and some small utility programs, modeled on the corresponding features in Multics, but simplified. The resulting system was much smaller and simpler than Multics.
August 1969: “Ken Thompson's wife took their son on a trip to California. As a temporary bachelor, Ken had time to work. [He told me] 'I allocated a week each to the operating system, the shell, the editor and the assembler … during the month she was gone, it was totally rewritten in a form that looked like an operating system'” – Peter Salus
Thompson needed a language to make utilities for Unix. At first, he tried #Fortran, but soon gave up and made a new language: #B, a simplified #BCPL.
1970: Multics was short for Multiplexed Information and Computer Services. Because the new unnamed OS was a single-tasking one, Brian Kernighan coined Uniplexed Information and Computing Service which spelled Unics, and was later spelled "Unix".
1972: Ritchie started to improve B, which was too slow and could not take full advantage of specific hardware, and ended up creating a new language, #C, which was then used to make utilities running on Unix.
1973: The Unix kernel, which was originally written in assembly language, was then re-implemented in C. By this time, C had acquired powerful features, such as struct types.
1977: Ritchie and Stephen C. Johnson made further changes to the language to facilitate portability of Unix. Johnson's Portable C Compiler served as the basis for several implementations of C on new platforms.
Mid-1960s: Bell Labs, MIT and General Electric were jointly developing an experimental time-sharing OS called Multics which was written in #PL_I and assembly language.
Late-1960s: Though Multics featured many innovations, it also presented severe problems, which frustrated researchers at Bell Labs until they gradually withdrew from the project.
1969: A team led by Ken Thompson and Dennis Ritchie, who were among the last to leave, decided to re-implement their experiences in a new, smaller project. They implemented a hierarchical file system, the concept of processes and device files, a command-line interpreter, and some small utility programs, modeled on the corresponding features in Multics, but simplified. The resulting system was much smaller and simpler than Multics.
August 1969: “Ken Thompson's wife took their son on a trip to California. As a temporary bachelor, Ken had time to work. [He told me] 'I allocated a week each to the operating system, the shell, the editor and the assembler … during the month she was gone, it was totally rewritten in a form that looked like an operating system'” – Peter Salus
Thompson needed a language to make utilities for Unix. At first, he tried #Fortran, but soon gave up and made a new language: #B, a simplified #BCPL.
1970: Multics was short for Multiplexed Information and Computer Services. Because the new unnamed OS was a single-tasking one, Brian Kernighan coined Uniplexed Information and Computing Service which spelled Unics, and was later spelled "Unix".
1972: Ritchie started to improve B, which was too slow and could not take full advantage of specific hardware, and ended up creating a new language, #C, which was then used to make utilities running on Unix.
1973: The Unix kernel, which was originally written in assembly language, was then re-implemented in C. By this time, C had acquired powerful features, such as struct types.
1977: Ritchie and Stephen C. Johnson made further changes to the language to facilitate portability of Unix. Johnson's Portable C Compiler served as the basis for several implementations of C on new platforms.
K&R C
Brian Kernighan had written the first C tutorial, and he persuaded Ritchie to co-author a book on the language.
1978, February 22, : Kernighan and Ritchie published The C Programming Language, known to programmers as "K&R". For many years it served as an informal specification of a version of C.
In this C, functions without a return type were assumed to return
K&R introduced:
• Standard I/O library
•
• Compound assignment operators of the form
And then gradually gained:
•
• functions returning struct or unions, rather than pointers
• assignment for structs
•
Late-1970s, and 1980s: C was implemented for a wide variety of mainframe computers, minicomputers, and microcomputers, including the IBM PC.
1980s: As C gained popularity the number of extensions and libraries for it grew. This, together with the fact that not even the Unix compilers precisely implemented the K&R specification, led to the necessity of standardization of both the language and the libraries.
1983: the ANSI formed a committee to establish a standard specification of C, to produce a superset of K&R C, incorporating many of the subsequently introduced unofficial features.
Brian Kernighan had written the first C tutorial, and he persuaded Ritchie to co-author a book on the language.
1978, February 22, : Kernighan and Ritchie published The C Programming Language, known to programmers as "K&R". For many years it served as an informal specification of a version of C.
In this C, functions without a return type were assumed to return
int. Function declarations also did not include arguments. Although compilers or Unix utilities such as lint were used to perform parameter count and type checks.K&R introduced:
• Standard I/O library
•
long int and unsigned int data types• Compound assignment operators of the form
=op were changed to op= to remove ambiguityAnd then gradually gained:
•
void functions, i.e., functions with no return value• functions returning struct or unions, rather than pointers
• assignment for structs
•
enumsLate-1970s, and 1980s: C was implemented for a wide variety of mainframe computers, minicomputers, and microcomputers, including the IBM PC.
1980s: As C gained popularity the number of extensions and libraries for it grew. This, together with the fact that not even the Unix compilers precisely implemented the K&R specification, led to the necessity of standardization of both the language and the libraries.
1983: the ANSI formed a committee to establish a standard specification of C, to produce a superset of K&R C, incorporating many of the subsequently introduced unofficial features.
Standard C
1989: the C standard was ratified as ANSI X3.159-1989. This version of C is often referred to as ANSI C, Standard C, or C89. It is still supported by current C compilers, and most C code being written today is based on it. Any program written in it, that has no hardware-dependent assumptions, will run correctly on any platform. It introduced:
• function prototypes, borrowed from #cpp
• void pointers
• support for international character sets and locales
• preprocessor enhancements
Although the syntax for parameter declarations was augmented to include the style used in C++, the K&R interface continued to be permitted, for compatibility with existing source code.
Even after the publication of the ANSI standard, for many years K&R C was still considered the "lowest common denominator" to which C programmers restricted themselves when maximum portability was desired, since many older compilers were still in use, and because carefully written K&R C code can be legal Standard C as well.
1988 April: A second edition of The C Programming Language book was released to cover the ANSI C standard, particularly on standard libraries. Though C has since undergone more revisions, no new editions have been issued.
1990: ANSI C was adopted by the ISO as ISO/IEC 9899:1990. Therefore, C90 and C89 are the same C.
1995: C95 (ISO/IEC 9899/AMD1:1995) was published to correct some details and to add more extensive support for international character sets.
1999: C99 (ISO/IEC 9899:1999) introduced:
• inline functions
•
• variable-length arrays
• flexible array members
• improved support for IEEE 754 floating point
• variadic macros (macros of variable arity)
• one-line comments with
Many of these had already been implemented as extensions in several C compilers.
2008: The C Standards Committee published a technical report extending the C language to address embedded programming with C which previously relied on non-standard extensions. Exotic features, not available in normal C, such as fixed-point arithmetic, named address spaces, and basic I/O hardware addressing, were added.
Late 2000s: work began on C1X, which added:
• type generic macros
• anonymous structures
• improved Unicode support
• atomic operations
• multi-threading, bounds-checked functions
It also:
• made some portions of the existing C99 library optional
• improved compatibility with C++
2011, December 8th: C1X, renamed to C11, was officially published.
2018, June: C18, the current standard for C, was released. It introduced no new features and only corrected and clarified technical defects in C11.
Nowadays, C is one of the most widely used programming languages and has found lasting use in applications previously coded in assembly language, such as OSs, and application software for platforms ranging from embedded systems to supercomputers.
1989: the C standard was ratified as ANSI X3.159-1989. This version of C is often referred to as ANSI C, Standard C, or C89. It is still supported by current C compilers, and most C code being written today is based on it. Any program written in it, that has no hardware-dependent assumptions, will run correctly on any platform. It introduced:
• function prototypes, borrowed from #cpp
• void pointers
• support for international character sets and locales
• preprocessor enhancements
Although the syntax for parameter declarations was augmented to include the style used in C++, the K&R interface continued to be permitted, for compatibility with existing source code.
Even after the publication of the ANSI standard, for many years K&R C was still considered the "lowest common denominator" to which C programmers restricted themselves when maximum portability was desired, since many older compilers were still in use, and because carefully written K&R C code can be legal Standard C as well.
1988 April: A second edition of The C Programming Language book was released to cover the ANSI C standard, particularly on standard libraries. Though C has since undergone more revisions, no new editions have been issued.
1990: ANSI C was adopted by the ISO as ISO/IEC 9899:1990. Therefore, C90 and C89 are the same C.
1995: C95 (ISO/IEC 9899/AMD1:1995) was published to correct some details and to add more extensive support for international character sets.
1999: C99 (ISO/IEC 9899:1999) introduced:
• inline functions
•
long long int and a complex type to represent complex numbers• variable-length arrays
• flexible array members
• improved support for IEEE 754 floating point
• variadic macros (macros of variable arity)
• one-line comments with
//Many of these had already been implemented as extensions in several C compilers.
2008: The C Standards Committee published a technical report extending the C language to address embedded programming with C which previously relied on non-standard extensions. Exotic features, not available in normal C, such as fixed-point arithmetic, named address spaces, and basic I/O hardware addressing, were added.
Late 2000s: work began on C1X, which added:
• type generic macros
• anonymous structures
• improved Unicode support
• atomic operations
• multi-threading, bounds-checked functions
It also:
• made some portions of the existing C99 library optional
• improved compatibility with C++
2011, December 8th: C1X, renamed to C11, was officially published.
2018, June: C18, the current standard for C, was released. It introduced no new features and only corrected and clarified technical defects in C11.
Nowadays, C is one of the most widely used programming languages and has found lasting use in applications previously coded in assembly language, such as OSs, and application software for platforms ranging from embedded systems to supercomputers.
Summary
1969: Ken Thompson led a team to implement Unix, and made B, to create utilities for it
1972: Dennis Ritchie, tried to improve B, ended up creating C
1973: Unix was mostly rewritten in C
1977: Stephen Johnson's Portable C Compiler served as the basis for implementations on new platforms
1978: Brian Kernighan and Ritchie published the K&R book which served as an informal specification for it
1989: ANSI standardized C
1990: ISO adopted ANSI C
1995: C95 corrected some stuff
1999: C99 introduced many things, many had already been implemented as extensions in compilers
2008: Embedded programming features, not available in standard C, were added to it
2011: C11 added many things, most of which were already common in other languages
2018: C18 corrected some stuff
1969: Ken Thompson led a team to implement Unix, and made B, to create utilities for it
1972: Dennis Ritchie, tried to improve B, ended up creating C
1973: Unix was mostly rewritten in C
1977: Stephen Johnson's Portable C Compiler served as the basis for implementations on new platforms
1978: Brian Kernighan and Ritchie published the K&R book which served as an informal specification for it
1989: ANSI standardized C
1990: ISO adopted ANSI C
1995: C95 corrected some stuff
1999: C99 introduced many things, many had already been implemented as extensions in compilers
2008: Embedded programming features, not available in standard C, were added to it
2011: C11 added many things, most of which were already common in other languages
2018: C18 corrected some stuff