Compiled from the internet Author: Zhao Yan/Serdar et al.
01. Why C Language Will Never Become ObsoleteEvaluating any programming language is always a controversial topic. It’s like in the chilly spring season, when people wearing cotton jackets and those in light clothing pass each other on the street, both silently think the same two words: “fool!” This phenomenon has a professional name in psychology: the “two fools” phenomenon!So why am I doing this controversial task? As the author of “Drops of Knowledge of C” and “C++”, and the translator of “New Thinking in C Language, Second Edition” (by Zhao Yan), I feel it is my responsibility to systematically introduce this language, its characteristics, and its future. This question is crucial for many newcomers entering the programming field, as they deeply worry about what will happen if C language becomes obsolete like Fortran.
First, here’s a table, which is the famous TIOBE programming language ranking. Currently, it is the most authoritative ranking of language popularity.In May, after five years, C language once again surpassed Java, claiming the top spot on the TIOBE programming language ranking!
The top ten are:C, Java, Python, C++, C#, Visual Basic.NET, JavaScript, PHP, SQL, and R.
Notice anything remarkable? That’s right, the first place has changed hands, C language has overtaken Java. It’s worth noting that C language last held the top position five years ago. What caused its “comeback”?After five years, C language returns to the top.
According to TIOBE CEO Paul Jansen’s speculation, “This may sound unbelievable, but certain programming languages can indeed benefit from such situations.”
Embedded languages (like C and C++) are becoming increasingly popular as they are used in software for medical devices.
For all programming languages, their ultimate goals are actually two:to improve hardware efficiency and to enhance programmer development efficiency.
Unfortunately, these two points cannot coexist! You can only choose one. In terms of improving hardware efficiency, C language has no competitors! For example, to implement a list, C language uses an array int a[3], which after compilation becomes a method of (base address + offset). For computers, no operation is faster than addition, and no method is faster than (base address + offset) access.
C language has compressed hardware efficiency to the extreme.This design philosophy brings about the problem of usability and safety. For instance, you cannot mix different types in an array, otherwise the compiler cannot calculate the correct offset. At the same time, C language is indifferent to incorrect offsets, which leads to the notorious out-of-bounds issue in C language.The C language’s claim of “trusting the programmer” is merely a beautiful phrase; its sole purpose is speed, either running fast or crashing fast. C language only cares about how high the program flies, not about how tired the programmer is. That’s just how it is!Now let’s look at those non-C languages; their strengths lie in improving programmer development efficiency.They either support dynamic lists or safe lists. However, adding any intermediate layer or safety checks cannot be faster than (base address + offset + no checks). There is no language in the world that is “easy to develop and fast to run”; ease of development comes from layers of wrapping over the underlying system.Now, let’s answer two common questions:With hardware being so cheap, is it necessary to make software faster?Most people with this doubt are regular customers in internet cafes, who understand computers only in terms of computer cities, and think of computing as just games and playing small movies from hard drives. Don’t get too excited about playing games with cheats; don’t forget about full-scale simulations, 3D rendering, and autonomous driving.When a person is driving, they need to collect 60 different objects every second and make 20 critical decisions based on the different combinations and reactions of these 60 objects. So even with the fastest hardware, autonomous driving still cannot claim to drive like a human. Even if autonomous driving succeeds, the next step is autonomous flying! Because we have long predicted: why not fly?So, to say:Computational speed is never enough! Because new applications will become increasingly complex and real-time.By the way! I forgot a more important limitation: computational energy consumption! The CPU on NASA spacecraft is at most 32-bit; you might not believe it, but there is not a single 64-bit CPU on the International Space Station. I guess one main reason is that astronauts don’t like watching movies on hard drives.Another popular question is: Can I invent a language that is just as fast but without so many pitfalls as C? The idea is possible, and coincidentally, there is such a language called D, but it hasn’t been widely adopted! This is due to a basic fact. There is now an overwhelming amount of C code, most of which is functioning normally, such as Linux, Windows, MacOS, Unix, Vxworks. You read that right; the kernels of these operating systems are all written in C. While I’m not sure about the proportion of C in Windows, I believe Microsoft wouldn’t be foolish enough to rewrite an operating system kernel entirely in C#.
You want these people to use your brand new language; that’s not just a bit naive, it’s downright foolish!Moreover, some code we simply cannot change! After NASA completed a simple flight control software with five CPUs, it had to undergo a “full coverage” test. What happens if CPU A fails? What if CPU A and B fail? What if CPU A and C fail? If you’re willing, you can do a simple mathematical combination. After testing, don’t even think about rewriting it; even adding a comment is not allowed. Because the supervisor in charge of the payload will seriously question you, why did the quantity of what you reported increase, but the quality did not improve? You need to explain to her in detail: hardware and software are different; hardware is that hard stuff you can touch, but software is not that soft stuff you can touch. Looking at the disdainful gaze of the supervisor, you will deeply regret the line of comment you carelessly added. Don’t take this lightly; this is a true story from NASA.So why has C language declined so much? It’s simple; some tasks are simply not meant for C language. When I was in school, I even used C language to write window interfaces, but soon Microsoft released MFC, which was a bunch of macros wrapping the underlying C window API.Later, this technology also became outdated. Because Microsoft realized that applications with windows are fundamentally not the job of C language, and if they keep wrapping it layer by layer, there’s a risk of exposing flaws, so they invented a brand new language, C#, to handle this task.Java is similar; it emphasizes networking, ease of use, security, and cross-platform capabilities. Whether it’s Java, C#, or Python, they intentionally avoid the issue of improving hardware efficiency because they cannot compete with C in this regard, nor can they shake the positions of existing C code in Linux, Unix, and GNU tools. What remains is to focus on enhancing programmer development efficiency, which is good for C language, shedding things it is not good at and allowing it to run faster!With the rise of embedded and real-time systems, AI, robotics, and autonomous driving, these are all core applications of C language, and in these applications, C language has no competitors.Therefore, I feel that C language will stabilize in its core applications and begin to gradually rise again.Finally, let’s talk about something trivial; C++ will not eliminate C language. Once you have objects, you will find that even the simplest objects consume resources, and once you have objects, you will inevitably think about inheritance. Once inheritance is implemented, you will find that the troubles brought by inheritance far exceed your imagination. When Java’s inventor James was asked what he would do first if he could redesign the Java language, he said: “Remove objects!” As a married programmer with two children, I can relate. If everyone is interested, I can write another blog discussing the real differences between C++ and C.
If you’ve read this far and haven’t remembered anything, just remember one thing: no one can predict the future.
If someone tells you that C language is already obsolete, it’s best to think for yourself; if you can seek the truth, that’s great; if not, at least remain skeptical.
02. Why Does C Still Dominate?
Especially true for a technology in the computer industry. Since its birth in 1972, C language has remained vibrant, and to this day it is still one of the foundational building materials we use to construct the software world.However, sometimes a technology can persist simply because people have not yet had the time to invent something new to replace it. Over the past few decades, many other languages have emerged—some explicitly designed to challenge C’s dominance, while others have tried to gradually undermine C language’s position through their popularity.Arguing that C needs to be replaced is easy. Programming language research and software development practices suggest how to do things better than C. Yet, after decades of research and development, C language’s position remains solid. Few other languages can outperform it in terms of performance, bare-metal compatibility, or versatility. However, how did C compete with those star programming languages in 2018? The details are still worth a look.C vs. C++Of course, C is most often compared with C++, as its name itself suggests, C++ was created as an extension of C language. The differences between C++ and C can be summarized as C++ being broader (in a positive sense) or more extensive (in a negative sense), depending on whether you ask a C or C++ programmer. (laugh)Although C++ retains many aspects of C syntax, it offers many practical features that are not available in native C: namespaces, templates, exceptions, automatic memory management, etc. Projects requiring top performance, such as those involving databases or machine learning systems, are often written in C++ to extract and utilize every bit of performance possible.Moreover, C++ is continuously expanding more actively compared to C. The upcoming C++20 will bring more features for developers to enjoy, including modules, coroutines, synchronization libraries, and concepts that make templates easier to use. The latest version of the C standard has only undergone minor updates and focuses on maintaining backward compatibility.In fact, all the additional features in C++ can also become burdensome. The more C++-specific features you use, the higher the complexity introduced, making it more difficult to correct results. Developers who limit themselves to just a subset of C++ can avoid many serious pitfalls and additional burdens in development. However, some teams want to fundamentally guard against C++’s excessive complexity. Sticking to C forces developers to limit themselves to a subset. For example, the Linux kernel development team directly avoids C++.Choosing C over C++ is feasible for you—and for any developers who will maintain your code—by adopting a forced minimalism to avoid entanglement with C++’s complexity. Of course, C++ has rich advanced features, which is justified. But if minimalism is more suitable for current and future projects—and for the teams responsible for those projects—then choosing C is wiser.C vs. JavaFor decades, Java has remained one of the mainstays of enterprise software development—and broadly speaking, one of the mainstays of development. Many of the most important enterprise software projects are written in Java—including the vast majority of Apache Software Foundation projects—and Java remains a viable language for developing enterprise-level demand projects.Java’s syntax borrows heavily from C and C++. However, unlike C, Java does not compile to native code by default. Instead, the Java Runtime Environment (JVM) JIT (Just-In-Time) compiles Java code to run in the target environment. In appropriate circumstances, JIT-compiled Java code can approach or even exceed C’s performance.The “write once, run anywhere” philosophy behind Java also allows Java programs to run with relatively few adjustments on the target architecture. In contrast, while C has been ported to many architectures, any given C program may still need to be tailored to run normally between, say, Windows and Linux, two different operating systems.This combination of portability and powerful performance, along with a vast ecosystem of software libraries and frameworks, makes Java the preferred language for building enterprise applications.Where Java falls short compared to C is in an area where Java never intended to compete: running close to the underlying structure or directly interacting with hardware. C code is compiled into machine code and executed directly by the process. Java is compiled into bytecode, which is an intermediate code that is subsequently converted to machine code by the JVM interpreter. Furthermore, while Java’s automatic memory management is an advantage in most cases, C is better suited for situations that must fully utilize limited memory resources.That said, in some respects, Java can approach C in speed. The JVM’s JIT engine optimizes routines at runtime based on program behavior, allowing for many types of optimizations that cannot be achieved in C, which is not pre-compiled. While Java runtime automatically performs memory management, some newer applications can address this issue. For example, Apache Spark partially optimizes in-memory processing by using custom memory management code that bypasses the JVM.C vs. C# and .NetNearly twenty years after its launch, C# and the .Net framework remain major components of the enterprise software world. Some say C# and .Net are Microsoft’s response to Java—a managed code compiler system and a common runtime library—many comparisons between C and Java also apply to C and C# or .Net.Like Java (and to some extent Python), .Net provides portability across various platforms and a vast integrated software ecosystem. Considering how much enterprise development exists in the .Net world, these are significant advantages. When you develop programs using C# or any other .Net language, you can leverage a wealth of tools and libraries written for the .Net runtime.Another advantage of .NET similar to Java is JIT optimization. C# and .Net programs can be pre-compiled like C language, but they are primarily JIT-compiled by the .Net runtime and optimized using runtime information. JIT compilation allows various in-place optimizations for .Net programs that cannot be executed in C.Like C, C# and .Net provide various mechanisms for direct memory access. Heap, stack, and unmanaged system memory can all be accessed through .Net APIs and objects. Developers can use the unsafe mode in .Net to achieve higher performance.But these come at a cost. Managed and unmanaged objects cannot be freely interchanged, and marshaling between them can degrade performance. Therefore, to maximize the performance of .Net applications, it is necessary to keep the movement between managed and unmanaged objects to a minimum.If you cannot afford the performance loss caused by the movement between managed and unmanaged memory, or if the .Net runtime is a poor choice for the target environment (e.g., kernel space) or may not be available at all, then C is what you need. Unlike C# and .Net, C is by default capable of unlocking access to memory.C vs. GoGo’s syntax borrows heavily from C—using braces as delimiters, statements ending with semicolons, etc. Developers proficient in C can usually use Go directly without much effort, and even Go’s unique features, such as namespaces and package management, are not difficult for developers.Code readability is one of Go’s guiding design goals: to allow developers to easily grasp any Go project and quickly become proficient in the codebase. C codebases can be difficult to understand because they can easily accumulate a lot of macros and #ifdefs specific to a project or team. Go’s syntax and its built-in code formatting and project management tools are designed to avoid such structural issues.Go also provides language-level tools for handling concurrency and messaging between components, such as goroutines and channels. C requires developers to manually handle these or rely on external libraries, but Go provides these features out of the box, making it easier to build software that requires them.The deepest difference between Go and C lies in memory management. By default, Go’s objects are automatically managed and garbage collected. This is very convenient for most programming tasks. However, it also means that any program requiring deterministic memory handling will be more difficult to write.Go does include an unsafe package for bypassing certain types of type safety in Go, such as reading and writing arbitrary memory using Pointer types. But unsafe comes with a warning that programs written with it “may be non-portable and not protected by Go 1 compatibility guidelines.”Go is well-suited for building command-line utilities and network services, as these rarely require overly detailed operations. However, for low-level device drivers, kernel-space operating system components, and other tasks requiring strict control over memory layout and management, it’s best to create them in C.C vs. RustIn some ways, Rust is a response to the memory management challenges posed by C and C++, as well as many other shortcomings of these two languages. Rust compiles to native machine code, so in terms of performance, it is considered comparable to C. But by default, memory safety is Rust’s main selling point.Rust’s syntax and compilation rules help developers avoid common memory management errors. If a program has a memory management issue that does not conform to Rust’s syntax, it will not compile. Newcomers to this language, especially those who have previously used C, often find that C provides ample room for such bugs, so their first step in learning Rust is to learn how to appease the compiler. However, Rust’s supporters argue that this short-term pain has a long-term payoff: safer code that does not slow down performance.Rust also improves upon C language through its tools. By default, project and component management is part of the toolchain provided by Rust, similar to Go. There is a default, recommended way to manage packages, organize project folders, and handle many other things that C requires to be handled separately, with each project and team managing them in different ways.However, what is touted as an advantage in Rust may not be very appealing to C developers. Rust’s compile-time safety features cannot be disabled, so even the smallest Rust program must comply with Rust’s memory safety constraints. By default, C may be less safe, but it is more flexible and forgiving when necessary.Another potential drawback is the size of the Rust language. Even considering the standard library, C’s feature set is relatively small. Rust’s feature set is very large and continues to grow. Like C++, a larger feature set in Rust means more powerful capabilities, but it also means higher complexity. C is a smaller language, making it easier to model in one’s mind, and thus may be more suitable for projects that are too small for Rust to warrant significant effort.C vs. PythonToday, whenever software development is discussed, Python seems to always appear in the conversation. After all, Python is the “second-best language for all projects” and undoubtedly one of the most versatile languages, with thousands of third-party libraries.The emphasis of Python, and what distinguishes it most from C, is favoring development speed over execution speed. A program that might take an hour to write in another language—like C—could be completed in minutes with Python. On the other hand, that program may take seconds to execute in C but take a minute to run in Python. (A good rule of thumb: Python programs typically run an order of magnitude slower than their corresponding C programs.) However, for many tasks on modern hardware, Python is fast enough, which is a significant reason for its widespread use today.Another major difference is memory management. Python programs are entirely managed by the Python runtime, so developers do not have to worry about the details of allocating and freeing memory. But similarly, the ease for developers comes at the cost of runtime performance. Writing C programs requires strict attention to memory management, but the resulting programs are often the gold standard for pure machine speed.However, in their bloodlines, Python and C share a deep relationship: the Python runtime reference is written in C. This allows Python programs to wrap libraries written in C and C++. Many important modules in the Python ecosystem, such as those in machine learning, have their core written in C code.If development speed is more important than execution speed, and if most of the high-performance parts of the program can be isolated into independent components (rather than spread throughout the code), then pure Python or a mix of Python and C libraries may be a better choice than using C alone. Otherwise, C remains the leader.03. Why C Language is Worth Learning1. In the embedded field, C language remains the preferred language.Embedded systems have not declined due to the development of other higher-level languages; they still demonstrate strong vitality in their own domain. Electronic products such as mobile phones, televisions, set-top boxes, air purifiers, etc., all fall within this domain, and they are unlikely to disappear in the short term. Moreover, with the rise of smart robots, the frequency of C language usage has begun to increase again.2. Operating system kernel code is still primarily in C language.In terms of language flexibility and execution efficiency, C language is still the most suitable language, and for system-level code, C language remains the preferred choice. Additionally, the underlying majority of many popular languages is built on C language. From this perspective, C language will never become obsolete; at most, its application scope may narrow, but its role remains powerful.3. The proportion of C language positions is relatively lower compared to application-level languages, but the entire software industry is developing, and the absolute number of C language programming positions has not decreased.Moreover, for programmers aspiring to become architects, C language is still a required course, as building software frameworks requires an understanding of the underlying systems. To take a step back, even if you feel that the proportion of C language positions is lower and harder to find, you can start with C language to build your knowledge system. Programming languages are tools; familiarizing yourself with one tool makes it easier to switch to other languages, and it also sets a good foundation for your career, preparing you for further advancement.The reason C language has remained popular for so many years is its distinct efficiency, convenience, and flexibility. Even if the probability of using higher-level languages decreases, it does not hinder its continued role at the system level. Every language has its social value. C language is still worth learning deeply as an introductory language.4. C/C++ programmers’ salaries have not been affected.According to data from 100offer, the highest annual salary for programmers who joined through 100offer has reached 470,000, while the lowest is 224,000. The income of C/C++ programmers has not shown a disadvantage compared to other programming language positions. As C/C++ gradually becomes the required language for certain specific companies and projects, the salaries of senior C/C++ programmers will also become more competitive.Zhihu influencer vczh said: “When I was in college, I almost only learned C/C++; later, during my internship at Microsoft, I found out that the team didn’t use C/C++; what to do? With the solid foundation that C++ gave me, I completed my boss’s task of ‘learning the basics of C# and WCF within two weeks’ on time and smoothly started working.”Of course, this is just vczh’s personal experience and does not represent the general case, but it is undeniable that C/C++ still has irreplaceability. A CTO of a startup stated in an interview: “Even though many people are singing the decline of C/C++, in modern times, there are still many projects whose target platforms temporarily only provide support for C/C++ compilers; from this perspective, C/C++ cannot completely disappear.”In terms of application scope, C/C++ is suitable for high-performance computing, embedded systems, server software development, games, real-time systems, network communication, etc. In the short term, there is no language that can completely replace C/C++, so it still has strong competitiveness.
04. Do I Need to Master Multiple Languages Besides C?
9 Reasons to Master Multiple Programming Languages
- Ability to solve the same problem in multiple ways; mastering different programming languages means having more options. After all, when you only have a hammer, everything looks like a nail.
- More competitive; having more job opportunities. Learning a second programming language can sometimes double the number of job opportunities. However, this depends on the types of languages you learn. Regardless, you will have more suitable opportunities, thus increasing your employability.
- Demonstrates your ability to learn new languages. Potential employers will see you as someone who is not rigid or stuck in their ways.
- Learning is fun. Learning new things keeps your mind excited. This will help you grow and improve in new areas.
- Stay updated with current technological trends. Knowing which industries are leading allows you to stay at the forefront of trends, ensuring your skills do not become obsolete.
- This will remind you why you should love your “main” language or how to do things better. Sometimes, only by trying a new language will you realize how excellent your main language is. You will appreciate your favorite language even more. Meanwhile, new languages may have some amazing features that make you feel like you’ve missed out.
- Helps you become a better programmer. Learning new languages helps improve skills that are common across all languages, such as designing and architecting algorithms or handling different data structures.
- Choose the best tools for the job. Every language has its strengths and weaknesses—some languages are better suited for certain aspects. By mastering multiple languages, you can select the best tools for your work.
- Demonstrates your strong learning ability. Nothing proves your learning ability better than mastering a second language.
9 Reasons Not to Master Multiple Programming Languages
- Mastering one language is easier. Generally, focusing and fully committing to mastering one thing is necessary. If you keep switching between multiple languages, the probability of truly mastering one language decreases. Mastering one language also helps you concentrate.
- Most people only need one job; most companies only use one language. Once you are hired, mastering multiple languages may not be helpful. Sometimes, just knowing the language used in the project is enough.
- There is always something worth learning; sometimes, this means delving deeper into one language.
- In most cases, experts can command higher salary demands because people are more willing to pay more for expertise. John Sonmez discusses in his video “I’m Not Sure I Want To Be A Specialist” why being a jack-of-all-trades is not always the best.
- Even mastering just one language can still make you a great developer. Whether you are a great developer has nothing to do with how many languages you know. The key is what you create. Because you are only dealing with one language, you can spend more time creating.
- You only need to learn a limited number of software development tools. Most languages have only a few tools. Switching languages often means switching tools. By mastering just one language, you can learn the related tools faster. This will help improve work efficiency.
- It’s easier to locate your market. By mastering just one language, you will basically settle in that direction (even if not by choice).
- You can solve most software problems with any one language. No matter how many people tell you, most languages can be used to solve any problem. If solving problems is your primary goal (which it should be), mastering more languages may not necessarily help achieve that goal.
- Understanding one thing deeply is better than having a superficial understanding of ten things.
This is not a black-and-white issue. Like other issues, the best solution is to find a middle ground: there is always a gray area. If you are a beginner, learning one language and applying it to the first ten projects will be easier. After that, I recommend becoming a “T-shaped” software developer.
What is a “T-shaped” Software Developer?
A “T-shaped” software developer has deep expertise in a specific area, represented by the vertical line of the T; additionally, they continue to learn broadly in another skill, represented by the horizontal line of the T.So, how does this relate to software development, especially learning programming languages? My advice is to master one programming language that will become your livelihood and solve most problems. You should do your best to master this language. On this foundation, you can learn the second language or skill that is most suitable for your work.T-shaped software developers are versatile, excelling in a specific field.In the journey to becoming a T-shaped developer, you will flexibly master multiple languages while also enjoying the advantages of being an expert in a particular domain.
Which Programming Language Should I Master?
A common question is which language to learn. Or, if you are a beginner, which language should you learn first? Generally, I would choose a language with some history as the primary language. This language should be used across multiple industries, have a broad user base, and a wealth of development tools. Languages that meet these criteria include but are not limited to: C, C++, Java, JavaScript, C#, Python, Go, etc.The TIOBE software index continuously tracks the popularity of programming languages based on these standards and compiles them into an index. You can click on the TIOBE Index to see the complete list of programming languages. The index is updated monthly, and most of the top 20 languages are good choices. Will these languages remain popular in the next ten years? I’m not sure. However, at least for the next few years, they are likely to remain popular, which I think is sufficient for any projects you are preparing to undertake.
To be honest, there is no absolutely correct or wrong answer to whether you need to master more languages; not discussing the demand for language selection is just playing around. Ultimately, the decision depends on your needs.
[References]1. Serdar Yegulalphttps://www.infoworld.com/article/3402023/why-the-c-programming-language-still-rules.html2. Zhao Yanhttp://zhaoyan.website/blog/index.php/2017/07/15/future/3. Anonymoushttps://dzone.com/articles/do-you-need-to-know-more-than-one-language