I often hear about C / C + +, and actually dislike each other. It will take you to understand the love and hatred between C language and C + +!

Time:2021-10-15

 

In the early 1970s, Bell Labs created C language, which is a by-product of unix development. Soon C became one of the most popular programming languages. But for Bjarne Stroustrup, C’s expression ability is not enough. Therefore, he expanded the C language in his doctoral thesis in 1983.

 

Thus, the C language supporting classes was born.

 

At that time, Bjarne Stroustrup understood that the programming language had many components. In addition to the language itself, there were compilers, linkers and various libraries. Providing familiar tools helps the language to be widely accepted. In this historical context, it is also reasonable to develop C + + based on C language.

 

After 40 years, both C and C + + have been widely used in the industry. However, c developers on the Internet believe that C + + is the worst human invention in history, and many C + + developers hope that C language will disappear one day.

 
 
 

C/C++Learning skirt [712]   two eight four   seven zero five  】, whether you areXiaobai is still an advanced person, whether you want to change your career or join it, you can learn about it, make progress together and learn together! There are development tools in the skirt, and many dry goods and technical data are shared![click me to enter]

 

1. What the hell happened?

 

On the surface, both C and C + + can meet the same use case: high-performance, deterministic, native but portable code, which can be used for the widest range of hardware and applications.

 

However, what makes C proud is that it is a low-level language, closer to assembly.

 

C + + has been full of strange things since the first day of its birth. For example, the black magic of destructors. A self assertive compiler. Although C + + had the function of type inference very early, developers in the mid-1980s could not accept this concept, so Bjarne Stroustrup had to delete auto until C + + 11 was added back.

 

Since then, C + + has been adding various tools to implement abstraction. It is difficult to say whether C + + is a low-level language or a high-level language. In terms of design purpose, C + + is both. However, it is difficult to establish high-level abstractions without sacrificing performance. So c + + introduces various tools to implement constexpr, move semantics, templates and growing standard libraries.

 

Basically, I think C trusts developers and C + + trusts compilers. This is a huge difference, which can not be covered up by simple consistency such as “the two have the same native type” and “the syntax of the while loop is the same”.

 

C + + developers blame C for these problems, while c developers think C + + is too crazy. I think it is also correct to look at C + + from the perspective of C. As a superset of C, C + + is really crazy. An experienced C developer may not feel familiar with C + +. C + + is not C, which is enough to trigger a heated debate on the Internet.

 

However, although I don’t like C, I have no right to make fun of C. Although I have some C + + experience, I have written very little code in C, and it must be very bad code. Good programming languages include good practices, patterns and idiomatic writing methods, which require years of learning. If you try to write c code in C + +, or write c + + code in C + +, it must feel bad. Even if you know C, you don’t necessarily know C + +, and vice versa. If you know C + +, you don’t necessarily know how to program in C.

 

So, should we stop talking about C / C + + and feel sad about these two unfortunate names? Not at all.

 

Although the design concept of C + + is different from C, C + + is still a superset of C. In other words, you can include the C header file in the C + + conversion unit, which can still be compiled. And that’s what caused the chaos.

 

C + + is not an extension of C, but a standard independently designed by different committees and different people. Logically, people who like the concept of C + + will participate in the C + + community and the process of C + + standardization, while others may try to participate in C. Both the C Committee and the C + + Committee can only express their intention and direction through their own final products: standards; The standard is the result of many votes.

 

However, it is difficult for the compiler to know whether it is processing C header files or C + + header files.

 

The extern “C” tag is not widely and consistently used, and it can only affect modification, not syntax or semantics. The header file only affects the preprocessor. For the C + + compiler, everything is a C + + conversion unit, so it is C + +. However, people still include C header files in C + + and expect it to “work” and do work most of the time.

 

So, we can’t help asking:

 

2. How can C + + code developed by different places and people maintain C compatibility?

 

I’m afraid it’s hard.

 

Recently, a colleague reminded me of Conway’s Law:

 

“The architecture of the design system is subject to the communication structure of the organization that produces these designs.”

 

According to this logic, if the two members do not cooperate with each other, the languages they create will not communicate with each other.

 

C + + maintains a list of incompatibilities with C and its standard libraries. However, the list does not seem to reflect many features added in C11 and C18 that are illegal in C + +. For a clearer introduction, see this wiki undergraduate page( https://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B )。

 

However, just listing the incompatibilities between the two languages is not enough to measure their incompatibility.

 

Functions that exist in the C + + standard library but are mainly declared from C are difficult to declare as constexpr, and even more difficult to declare as noexcept. C compatibility will lead to performance cost, and C function is an obstacle to optimization.

 

Many C structures are valid in C + +, but cannot pass code review (such as null, longjmp, malloc, constructor / destructor, free, C-style type cast, etc.).

 

In C’s view, these idiomatic writing methods may not be a problem, but not in C + +. C + + has a more powerful type system. Unfortunately, the idiomatic writing of C chisels a hole in this type system, so realizing C compatibility needs to pay a price in terms of security.

 

Don’t get me wrong, C + + still cares about C compatibility, to some extent. Interestingly, however, C also cares about C + +, to some extent. To be honest, C may care more about C + + than C + +. It seems that each committee still cares about the work of another committee. But we are reluctant.

 

C + + knows that many basic libraries are written in C, including not only libc, but also zip, PNG, curl, OpenSSL (!) and many other libraries, which are used by countless C + + projects. C + + cannot break these compatibility.

 

But recently, especially in the past decade, the scale of C + + has far exceeded that of C. C + + has more users and the community is more active. Perhaps this is why the size of the C + + Committee is more than 10 times that of the C Committee.

 

C + + is a force that can not be ignored, so the C committee must consider not damaging C + + compatibility. If we have to say that one standard follows another, then c + + is the leader and C is the follower.

 

Now, C + + is in a stable three-year cycle, whether it is wind and rain, hot sun, or a deadly new epidemic. C releases the main version every ten years or so. However, this is also reasonable, because as a lower level language, C does not need to develop so fast.

 

The environment of C language is also completely different from C + +. C is mostly used for platforms and more for compilers. Everyone (even their dog) can write a C compiler, because the feature set of the language is very small, so anyone can write a C compiler. There are only four implementations really considered by the C + + Committee, and these four implementations will appear at each meeting. Therefore, many functions in C language are implementation related or optional support, so that various compilers can claim that they comply with the standard without much effort. It is said that the people of the committee will be more happy.

 

Nowadays, C + + focuses more on portability than freedom of implementation. This is another difference in concept.

 

3. Therefore, your proposal undermines C’s compatibility

 

Part of my proposed p2178 will theoretically affect compatibility with C. In that case, none of the plans will be satisfactory.

 

One might say that you can first propose your new features to committee C. This means that more meetings are needed. The strict rules of attendance at the C conference may prevent you from attending the conference, which will shut out individuals who are unwilling to spend thousands of dollars to become ISO members. This is because committee C must abide by the rules of ISO.

 

Moreover, if the new standard has just been released, it may take another ten years for your proposal to be considered. Most importantly, if committee C does not understand or care about the problem you are trying to solve, your proposal will sink into the sea. Or they may not have the energy to deal with the problem. And maybe you don’t have the energy to deal with C. After all, your intention is to improve c + +. In fact, even if no one objects to your proposal at the meeting (although it is unlikely to happen), if someone asks you to discuss it with the people of committee C first, you will be sentenced to death for your proposal.

 

Another possibility is that the C committee accepts a slightly different version from the version existing in C + +. True can only be implemented as a macro. char16_ T requires typedef. char32_ T is not necessarily UTF-32. static_ Assert corresponds to_ Static_ assert。

 

There are still many such situations. Should we blame C? Probably not. Their committee is just trying to do well in C. vice versa. In C + + 20, the specified initializer is inspired by C, but adopts slightly different rules, because if it is exactly the same, it does not comply with the C + + initialization rules.

 

I am also responsible for this problem. C has VLA. If I had been, I would have opposed using it in standard C + + because it caused too many security problems. I will also firmly oppose_ Proposal to add generic to C + +. Maybe_ Generic aims to reduce problems caused by lack of templates or overloading, but C + + has these two functions. From my point of view_ Generic is not suitable for C + + in my imagination.

 

The two committees also seem to have different concerns about each other’s language. Sometimes we encounter very good compatibility (STD:: complex), and sometimes we don’t care about compatibility at all (static array parameters).

 

There’s no way. Don’t forget that every committee is a group of people who vote at different times and places, and trying to control the results will lead to meaningless voting. It’s not realistic to put these people in the same room. ISO may object that the imbalance of participants will put C’s people at a great disadvantage.

4. C compatibility is not important

 

If you are a C developer, you will certainly regard C as a concise programming language. But for the rest of us, C’s impression is completely different.

 

C is a universal, cross language glue that can closely combine everything.

 

For C + + users, C is their API. From this point of view, the value of C lies in its simplicity. Remember that the part of C that C + + cares about is C that appears in the interface (header file). We are concerned with declarations, not definitions. C + + needs to call functions in the C library (Python, FORTRAN, rust, D, Java and other languages are the same. In all cases, C can be used at the interface boundary).

 

Therefore, C is an interface definition language. The more you add to C, the more difficult it is to define interfaces. These interfaces are less likely to remain stable over time.

 

So, what is missing in C + +Is it important? It may not be important because it is unlikely to appear in a public interface.

 

5. Now everyone is talking about C

 

In the past, C compatibility was a big selling point of C + +. But now, everyone (and even their goldfish) knows C. Rust can call C functions, python, Java and all languages! Even weird Javascript can call C function in WebAssemby.

But in these languages, interfaces are explicit. The language provides tools to expose specific C declarations. Of course, it’s troublesome. But this makes the interface very, very clear. And it’s bounded. For example, in rust, calling C function does not force Rust to sacrifice certain designs to accommodate C subsets. In fact, C is included.

mod confinment {
    use std::os::raw::{c_char};
    extern "C" {
        pub fn puts(txt: *const c_char);
    }
}
pub fn main() {
    unsafe {
        confinment::puts(
            std::ffi::CString::new("Hello, world!").expect("failed!").as_ptr()
        );
    }
}

 

6. Compiler Explorer

 

Unless the ABI of C changes, this code can run normally all the time. Moreover, the boundary of rust / C is very clear and self-evident.

 

Therefore, C + + is probably the language that pays the most for C compatibility.

 

What’s worse, open any C header file and you’ll soon find a pile of #ifdef files__ cplusplus。 Yes, C + + compatibility often requires a lot of work from C developers. Compatibility has always been a mirage. Many people know my tweet:

 

7. Where should we go?

 

I think both committees are trying to communicate more. They plan to hold a meeting in Portland next year (although the plan may change). Communication is a good thing.

 

But the communication effect of chicken and duck will be very limited. The design pillars of both languages may not be coordinated. I will try to suggest providing a template. But first, I have to make complaints about C language without modules, namespaces, and what the whole macro is.

 

Maybe you can restrict the C subset acceptable to C + + to C99? Maybe both languages need to find a common subset and develop independently? Maybe extern C needs to affect parsing. If C + + has gone through many times, C may be one of them.

 

Maybe we need to accept C as a subset of C + +, but the only way is to integrate wg14 into wg21.

 

The status quo may not change. C + + may never be free from its origins, and C may always have to fight the dirty features in the name of the C language.

 

C/C++be applied toWindowsOperating system, driver, patch, image processing, audio and video processing, industrial control software, embedded (mobile phone, intelligent machine), etc,C++ It has become one of the most popular languages for developers and consolidated global systems and services.

 

 

 

If you’re rightInterested in programming and want to learn more. Here to share the material package and learning resources, as well as free tutorials (including CLanguageC++WindowsQtLinuxRelevant knowledge points)~Whether Xiaobai or advanced, you can grow here.