C ++ Design and Evolution: Excerpts

    In the comments on the translation “30 years of C ++”, it was noted that not all stages of the evolution of the language are equally well known, sometimes there is no idea at all about the origin and development process of a particular syntax element or corresponding semantics. Perhaps this article will be able to interest the readers in a long time ago not a new book by the author of the language in order to form a more complete picture of C ++. The book tells how its development took place, what influenced this process and why some approaches were preferred over others.

    The following is a set of short excerpts from the book, presented in free form and sometimes supplemented by examples. The order of presentation basically repeats the relative order of their appearance in the book. Numbering is used for possible references to individual items. There will not intentionally be a repetition of well-known facts, since this does not make much sense. Attention was paid to the less well-known of them and the most interesting from the point of view of the author of the post. Some points are quotes that say it all; a number of others just mention potentially interesting or funny facts. Also, many details are omitted, they should be sought in the book.

    Some of the material overlaps somewhat with recent posts, but has not been cut for completeness. The order may seem chaotic, but for that it is a sample, an additional reason for the "mess" is indicated in the conclusion. When reading, it is useful to keep in mind that the first edition of the book came out in early 1994.

    Excerpts


    1. It all started in 1971, when Björn Straustrup needed a fast language for modeling.

    2. Classes came primarily from Simula .

    3. const-qualifiers owe their existence to ROM .

    4. Dennis Ritchie was actively involved in the discussion of C ++ design. (Below you will see how much C and C ++ influenced each other.)

    5. “Initially, the language proposed general mechanisms for organizing programs, and not at all support for specific subject areas”, i.e. C ++ multi-paradigm is innate and corresponds to the idea of ​​its author.

    6. “I am sincerely convinced that there is no one right way to write a program, and a language designer should not force a programmer to follow a certain style.”

    7. The initial implementation did not support virtual functions.

    8. Multiple inheritance was added years after the start of language development.

    9. Initially, class constructors were called newand returned void(although it could be omitted). At the same time, it was the designers who allocated memory for the object, and the destructors freed it:
      classstack
      {voidnew();
          // new();
      };
      

    10. The original name of the destructors was deleteand they also returned void(although it could be omitted):
      classstack
      {voiddelete();
          // delete();
      };
      

    11. Instead of a double colon ( ::), a dot was used to declare class methods:
      charstack.pop()
      {
          // ...
      }
      

    12. Class names resided in a separate namespace and should have been preceded by a keyword class(as well as struct/ unionin C):
      classstackstack;classstack *thatStack = &stack;

    13. The key word itself classcame from Simula, and since Björn was not a fan of inventing terminology, he left what he was used to.

    14. The Simula language allowed creating instances of classes only on the heap, which was extremely inconvenient and gave the idea to allow creating them in C ++ on the stack or globally.

    15. “C ++ is just another language in the system, not the whole system.”

    16. In the first implementation, there was no way to access this, but this was more a consequence of the error.

    17. Autoprototyping (displaying and storing a prototype of an unknown function at the place of the first call to it) was originally invented for C ++, but was later used in C (although it is now deprecated now):
      function(1, 1.0);   // Компилятор запоминает, что function принимает int и double.
      function("string"); // Компилятор выдаёт ошибку из-за несоответствия типов аргументов int и double.

    18. The declaration of a function that does not accept arguments using (void)was added first in C ++, and only then in C (then in C ++ this idea was already abandoned and decided to use empty parentheses):
      voidnoArgsInCpp();
      voidnoArgsInCAndCpp(void);
      

    19. Declaring an implicit intas deprecated was originally proposed for C ++:
      function() {} // Компилятор предполагает, что function возвращает int.

    20. In the early periods, attempts were made to prohibit narrowing transformations ( long -> int, double -> int), but because of too much prevalence, it was decided to abandon this idea:
      voidf(long lng, int i){
          i = lng;    // Вызвало бы ошибку.char c = i; // Вызвало бы ошибку.
      }
      

    21. Operator overloading, links and the ability to declare variables anywhere in the block came from ALGOl 68 .

    22. Single-line comments ( //) are from the BCPL .

    23. Sources used in the development of exceptions: Ada , Clu , ML .

    24. Templates and namespaces are borrowed from the Ada language.

    25. Specifying parameter types in a function declaration - first implemented in C ++, later adapted in C.

    26. We considered the possibility of introducing an alternative syntax for declarations (recently there was a post on a related topic):
      // Радикальный вариант:
      v: [10]->int; // int *v[10];
      p: ->[10]int; // int (*p)[10];// Менее радикальный вариант:int v[10]->; // int *v[10];int p->[10]; // int (*p)[10];intf(char)->[10]->(double)->; // int *(*(*f(char))[10])(double);
      The new syntax was not worked out in all details and it never got into the language due to the small significance of the change against the background of potentially large problems with backward compatibility.

    27. The rejection of mandatory type prefixes ( struct/ union/ class) made it possible to declare variables matching the names of classes (by and large, for the sake of compatibility with C):
      classClass
      {
      };
      intmain(){
          Class Class;
          return0;
      }
      

    28. At one time, the declaration of new composite types was allowed in the argument list or directly in the return value of the function:
      classA
      {// ...
      } get()
      {
          return A();
      }
      

    29. Previously, “pulling” the members of the base classes did not require the use of a keyword using, it was enough just to specify the name of the member:
      classBase
      {protected:
          voiddoSomething();
          voiddoSomethingElse();
      };
      classDerived :public Base
      {
      public:
          doSomething; // using doSomething;
          Base.doSomethingElse; // using doSomethingElse;
      };
      

    30. Initially, friendonly classes could be friendly ( ). The general idea of ​​the concept is to place a number of entities in one security domain, the members of which are equal in rights (rather than violating encapsulation, how can one get the impression that, however, does not cancel out the possibility of such use).

    31. Perhaps it was Straustrup who invented the concept of designer.

    32. Initially, each object could contain call()and methods return()that were called respectively before and after the execution of any class method. Similar methods :beforeand :afterare in CLOS .
      classProtectedAccess : object
      {
          call();   // Захватить примитив синхронизации.return(); // Освободить примитив.
      };
      
      Later it was decided that this feature adds more difficulty to the language than it benefits.

    33. The possibility of including a garbage collector in the language was considered several times, but was found to be unacceptable.

    34. Direct support for multithreading was also considered, but it was decided to leave it for implementation as a library.

    35. For a while, the language was called C84 to avoid confusion, as users replaced C with classes with something like “new C”, “improved C”, etc. Optimistically considering that C would be standardized in 1985, Björn was asked to change the name again, in order to avoid possible ambiguity with “standard C”.

    36. The first C ++ compiler (not the preprocessors that were originally used) was written in C ++ (Cfront, C with classes and C84, it seems, were written in C).

    37. Cfront was probably the first partial-cycle compiler to generate C code. It was followed by Ada, Eiffel , Lisp , Modula-3 , Smalltalk .

    38. The first exception implementation was added by Hewlett-Packart in 1992.

    39. Virtual functions were borrowed from Simula, but with modifications.

    40. The type definition at runtime was not initially intentionally added to force users to use static type control and virtual functions, rather than a run-time type, which in essence is switch.

    41. structalmost equivalent classfor the purpose of uniformity and unification.

    42. Before Cfront 2.0, it operator=could be a global function, later abandoned this idea due to conflicting predefined semantics.
      classC {};
      C & operator=(C &rhs) {}
      // Приводит к ошибке:// src.cpp:3:21: error: ‘C& operator=(C&)’ must be a nonstatic member function

    43. The definition of the variable at the point of use is taken from ALGOL 68.

    44. Links are also borrowed from ALGOL 68, but there they could be reassigned after initialization.

    45. Overloading with lvalue / rvalue was considered back in the days of Cfront 1.0.

    46. readonly / writeonly pointers / data were invented by Straustrup and Dennis Ritchie in 1981, and were later added to the C standard by the ANSI C committee (X3J11), but in a somewhat truncated form: only readonly and after it was renamed to const.

    47. The keyword is newalso taken from Simula.

    48. The initial implementation of object placement involved assignment thisin the constructor.

    49. constructor/ destructoras the names of the corresponding special methods were rejected to reduce the number of keywords, as well as for a more obvious syntax.

    50. Functions new()and delete()(old constructor and destructor names) in C with classes by default automatically received an access modifier public.

    51. An operator ::was introduced to resolve the ambiguity with a dot.

    52. Initially, the variables entered in the initialization list forwere visible after his body (due to the inaccurate wording “names are visible from the place of declaration to the end of the field”). Many have probably come across this in Borland C ++.
      for (int i = 0; i < n; ++i) {
          // ...
      }
      if (i >= n) { // То же i, что объявлено в for.

    53. Nested class scopes were added, later removed for C compatibility, and re-added again.
      // Этот код работает и в C и в C++:structOuter
      {structInner { };
      };
      // Но в C он эквивалентен следующему:structOuter { };
      structInner { };
      

    54. static the default for global characters was against the rules of C and for this reason was not added in C ++.

    55. Strict type control when calling functions in C came from C ++.

    56. “The key to good design is a deep understanding of the challenges facing the language, rather than incorporating cutting-edge ideas.”

    57. Abstract classes, type-safe layout, and multiple inheritance appeared in Cfront 2.0.

    58. The random order of declarations of class members caused problems and led to some inequality between types and data. Doing so is allowed:
      int x;
      classX
      {intf(){ return x; } // x означает X::xint x;
      };
      
      And it’s already forbidden:
      typedefchar *T;
      classY
      {T f(){ T a = 0; return a; } // Ошибка, т.к. T меняет своё значение на следующей строке.typedef f int T;
      };
      
      The same is true for function types, because:
      typedefintP();
      classX
      {staticP(Q1); // static int Q1();static P Q2;  // static int Q2();
      };
      

    59. In Cfront, temporary objects were destroyed at the end of the block (now - after evaluating the expression, if the temporary object is not bound):
      constchar *p;
      std::string s1 = ..., s2 = ...;
      if ((p = (s1 + s2).c_str()) && p[0]) {
          // Здесь можно было работать с p.// ...// Тут уничтожался временны объект, созданный выражением "s1 + s2".
      }
      

    60. It might still be news for someone, but Pascal also has ISO / IEC standards (there are just a few such languages ).

    61. The proposal to add named arguments was considered but rejected. (When reading the book, the impression was that a rather large number of different proposals were rejected; however, much of this still fell into standard after decades.)

    62. restrict (noalias) pointers were never adapted from C even though they were known in the early 90's.

    63. Special characters caused C distribution problems in Europe due to the widespread use of 7-bit encodings. From here came the trigraphs, digraphs, and special words ( and, oretc .; see ). All this migrated to C ++.

    64. The budget that AT&T has allocated in C ++ for the entire time is approximately $ 3000. Of these, $ 1000 went to the distribution of C ++ advertisements to UNIX customers and $ 2000 to the first conference, at which everything was more than modest (even not enough paper, the volunteers made copies of the technical documentation on the visitor registration forms ...). Nevertheless, the absence of any kind of marketing for decades has not prevented the widespread use of the language.

    Conclusion


    In conclusion, I would like to mention the somewhat non-standard structure of the book (therefore, the order of the items might seem strange) with an increase in the level of detail in each part, as well as the fact that it outlines the principles that Straustrup is trying to adhere to and their rationale. Therefore, it should be of interest not only to C ++ programmers, but also to many who are interested in programming languages ​​in general.

    Also popular now: