Understanding the C Family: C, C++, Objective-C, and C#
C Programming Languages
Learning Objective-C has made me wonder, why are there so many languages starting with the letter “C”? I thought it would be good to read up and understand the history, paradigms, and key differences between C, C++, Objective-C, and C#. This is just my own notes to mentally map the relationship and understanding of these languages.
Venn Diagram
Source: Stack Overflow
Components:
- C (Red) as the foundation, as it is the oldest and foundataional language. C++ and Objective-C are built as supersets of C. Conceptually and mostly in practice, valid C code is also valid C++ and valid Objective-C code…
- C++ (Yellow): C++ adds object-oriented features (classes, objects, inheritance), generic programming (templates), and other features on top of C. A small, carefully written C program is often valid C++.
- Objective-C (Blue): Objective-C adds object-oriented features from Smalltalk (like dynamic dispatch/message passing) and modern memory management (ARC) on top of C. A small C program is often valid Objective-C.
Others:
- Grey Area (C and C++ overlap outside C): Features that are part of both C and C++, but not from original pure C, or features introduced by C++ that are considered good practice for both but were not in the original standard.
- More accurately, it represents C code that uses features added in later C standards (like restrict in C99, though C++ has a similar keyword) that are compatible with C++. It’s better thought of as “C-like C++ code.”
- Green Crescent (Subset of C invalid in C++): C++ is not a perfect superset. Almost, but not entirely. C and C++ have subtly different syntax and features, especially around declarations, function protoypes, and pointer safety.
- For example, C allows you to declare a variable after the first statement in a block (since C99), whereas earlier C++ (like C++98) did not always allow this. C allows int f() to mean “a function that takes any number of arguments,” while in C++, it means “a function that takes zero arguments.” Crucially, C allows implicit pointer casting from void*, which C++ forbids.
Then what about Obj-C and C++ Overlap?
- Objective-C and C++ Overlap: You can mix C++ and Objective-C code in the same source file, which is then known as Objective-C++. This is used, for example, when an iOS developer wants to use a powerful C++ physics engine within an Objective-C application.
- E.g. Renaming a
.mfile to a.mmfile tells the compiler to treat the file as Objective-C++, allows mixing of Obj-C syntax[object message]and C++ syntaxstd::vector,std::string,new/delete, templates in the same file. - Need to be careful not to include C++ headers inside public header file, use opaque pointers. There are memory management differences as well, C++ memory managed manually won’t participate in ARC automatically. Also need to use bridging types for fundamental types.
- E.g. Renaming a
1. C (The Foundation)
The C programming lanugage is an imperative, procedural language developed in the early 1970s by Dennis Ritchie at Bell Labs. It was designed to write the Unix operating system and be a systems programming language.
- Naming: The “B” programming language, the predecessor of C, was said to be named after the predecessor BCPL (Basic Combined Programming Language), or a short form of Bon, an earlier language by the designer Ken Thompson working with Dennis Ritchie. After B (1969) there was actually “NB”, or new B (1971), then came C as the finalized successor.
- Procedural, low level language, sits very close to the hardware.
- Because C has a lot of relatively direct access to features of the hardware, it is a very fast language. In Linus Torvalds Q&A, Linus mentions how using C for Linux is low level enough for him to optimize path name lookups to reduce single cache misses.
- It is used in Operating system kernels (Linux, Windows, MacOS), embedded systems, IoT devices and other performance-critical applications.
Some Properties:
- Paradigm: Imperative, Procedural
- Memory Management: Manual (
malloc/free) - Key Characteristics: Low-level, extremely fast, direct hardware access, basis for modern operating systems.
C has a very simple and barebones syntax, requiring own libraries etc. All executable code is contained in functions, parameters are passed by values, (pass by reference through pointers), supports recursion, run-time polymorphism done by function pointers.
Data typing is weakly enforced and static, implicit conversion between data types (coercion, e.g. can add a char and an int), do arbitrary type casting etc. Weak typing allows the low-level freedom to manipulate memory addresses and hardware registers directly, tradeoff safety for the execution speed.
References:
- https://en.wikipedia.org/wiki/B_(programming_language)
- https://en.wikipedia.org/wiki/C_(programming_language)
2. C++ (C with Classes)
C++ came out in 1985, designed by Bjarne Stroustrup at Bell Labs as an extension of C, adding support for Object-Oriented Programming (OOP) without sacrificing C’s raw performance. Originally called “C with Classes” in 1979, it was renamed to C++ in 1983 (using the increment operator ++ in C to signify it as the next step forward).
- Superset of C: C++ was designed so that valid C code is mostly valid C++ code, making it easy for existing systems to adopt.
- Zero-Cost Abstractions: Stroustrup’s design motto: “What you don’t use, you don’t pay for. And further: What you do use, you couldn’t hand code any better.”
- RAII (Resource Acquisition Is Initialization): Ties resource management (memory, file handles, locks) to object lifetime, avoiding manual cleanup errors.
- Modern C++ Features: Standard Template Library (STL), templates, smart pointers (
std::unique_ptr,std::shared_ptr), and lambda expressions. - Use Cases: Game engines (Unreal Engine), web browsers (V8 / Chrome engine), financial high-frequency trading systems, operating systems, and graphics software.
Some Properties:
- Paradigm: Multi-paradigm (Procedural, Object-Oriented, Generic, Functional)
- Memory Management: Manual / RAII (
new/delete, Smart Pointers) - Key Characteristics: High performance, compiled directly to native machine code, template metaprogramming.
References:
- https://en.wikipedia.org/wiki/C%2B%2B
3. Objective-C (C + Smalltalk Messaging)
Objective-C was developed in the early 1980s by Brad Cox and Tom Love at Stepstone. Unlike C++, which added SIMULA 67-style object-oriented features to C, Objective-C added dynamic Smalltalk-style messaging to C.
- Naming & Syntax: It is a strict hybrid extension of C with a unique bracketed syntax for passing messages between objects, e.g.
[receiver message:argument]. - Dynamic Dispatch / Smalltalk Messaging: In C++, function calls are resolved at compile-time (or via vtables for virtual methods). In Objective-C, sending a message is resolved at runtime via the Objective-C runtime (using
objc_msgSend). If an object doesn’t implement a method, it can dynamically handle or forward it. - NeXTSTEP & Apple Lineage: NeXT (founded by Steve Jobs after leaving Apple in 1985) licensed Objective-C as the main language for NeXTSTEP OS. When Apple acquired NeXT in 1996, NeXTSTEP became the basis for Mac OS X (now macOS) and later iOS, making Objective-C the standard language for Apple app development for over two decades until Swift debuted in 2014.
- Objective-C programs developed for non-Apple operating systems or that are not dependent on Apple’s APIs may also be compiled for any platform supported by GNU, GNU Compiler Collection (GCC) or LLVM/Clang.
Some Properties:
- Paradigm: Object-Oriented, Dynamic Dispatch
- Memory Management: Originally Manual Reference Counting (
retain/release), later Automatic Reference Counting (ARC) - Key Characteristics: Strict superset of C, highly dynamic runtime environment, foundational to classic Apple APIs (Cocoa / Cocoa Touch).
One quirk is that Objective-C source code “messaging/implementation” program files usually have .m filename extensions, while Objective-C “header/interface” files have .h extensions, the same as C header files. Objective-C++ files are denoted with a .mm filename extension.
Objective C compiles directly to native machine code, and relies on a dynamic C-based runtime. In contrast, for e.g. Android development, Java and Kotlin are designed to compile to bytecode, executed into a Java Virtual Machine (JVM). Interesting differences, I wonder how the languages shape the software architecture for each. Maybe I will investigate this topic in another post!
So why did Apple choose ObjC for so long? It is likely that Apple prioritized the control over the entire ecosystem, instead of adopting Java (Oracle - Google fought legal battles because of this). Additionally, less overhead in running a JVM.
References:
- https://en.wikipedia.org/wiki/Objective-C
- https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html
4. C# (Microsoft’s Managed C-Derivative)
C# (pronounced “C Sharp”) was introduced by Microsoft in 2000 as part of the .NET initiative, led by chief architect Anders Hejlsberg (who also created Turbo Pascal and Delphi, and later co-created TypeScript).
- Naming: The name “C#” was inspired by musical notation, where a sharp sign (
♯) denotes that a note should be made one semitone higher in pitch. Visually, it can also be thought of as four+symbols in a 2x2 grid (C++++). - Managed Execution & .NET CLR: Unlike C, C++, and Objective-C which compile directly to native machine code, C# compiles to Intermediate Language (IL). The .NET Common Language Runtime (CLR) then executes IL using a Just-In-Time (JIT) compiler.
- Safety & DX: Eliminates raw pointers (unless inside an
unsafeblock), provides automatic garbage collection, type safety, properties, events, LINQ (Language Integrated Query), and async/await concurrency primitives. - Origins vs Java: C# was initially seen as Microsoft’s response to Java, but over the last two decades, it has evolved rapidly into a feature-rich, cross-platform language (via .NET Core / modern .NET).
- Use Cases: Enterprise web backends (ASP.NET Core), cross-platform desktop/mobile applications (.NET MAUI), and game development with Unity.
Some Properties:
- Paradigm: Multi-paradigm (Component-oriented, Object-Oriented, Functional features)
- Memory Management: Automatic (Garbage Collected)
- Key Characteristics: Runs on the .NET CLR runtime, strong type safety, modern language features, cross-platform.
References:
- https://en.wikipedia.org/wiki/C_Sharp_(programming_language)
- https://learn.microsoft.com/en-us/dotnet/csharp/tour-of-csharp/
Table Comparison
| Feature | C | C++ | Objective-C | C# |
|---|---|---|---|---|
| Year Released | 1972 | 1985 | 1984 | 2000 |
| Primary Creator | Dennis Ritchie | Bjarne Stroustrup | Brad Cox & Tom Love | Anders Hejlsberg (Microsoft) |
| Paradigm | Procedural | Multi-paradigm (Procedural, OOP, Generic) | Object-Oriented (Smalltalk Messaging) | Multi-paradigm (Component/OOP, Functional) |
| Execution Output | Native Machine Code | Native Machine Code | Native Machine Code | IL Bytecode (JIT via CLR) / Native AOT |
| Memory Model | Manual (malloc / free) | Manual / RAII (new / delete, Smart Pointers) | Automatic Reference Counting (ARC) / Manual | Automatic Garbage Collection (GC) |
| Method Dispatch | N/A (Function Pointers) | Static / Compile-time (vtable for virtual) | Dynamic Dispatch (objc_msgSend) | Static & Virtual / Runtime (CLR) |
| Primary Use Cases | OS Kernels, Embedded Systems, Drivers | Game Engines, High-Freq Trading, Browsers | Legacy Apple Ecosystem (iOS / macOS) | Enterprise Backends, Unity Games, .NET Apps |
Summary & Mental Model
While all four languages share the syntax lineage established by Dennis Ritchie’s C (curly braces, control flow, and operator conventions), they serve fundamentally different architectural tiers:
- C is the minimal, blazing-fast foundation that sits directly on hardware registers and kernel memory.
- C++ extends C with zero-cost abstractions, template metaprogramming, and RAII for high-performance systems.
- Objective-C overlays C with dynamic Smalltalk messaging, powering Apple’s developer ecosystem for over two decades.
- C# brings C syntax into a managed, garbage-collected environment optimized for developer velocity, type safety, and cross-platform enterprise software.
