请输入您要查询的百科知识:

 

词条 Criticism of C++
释义

  1. Slow compile times

  2. Global format state of

  3. Heap allocations in containers

  4. Iterators

  5. Uniform initialization syntax

  6. Exceptions

  7. Strings without Unicode

  8. Code bloat

  9. See also

  10. References

     Works cited 

  11. Further reading

  12. External links

{{Multiple issues|{{original research|date=June 2016}}{{unreliable sources|date=June 2016}}

Some of the problems might be related to the compiler used and not the language itself.}}

{{Use dmy dates|date=December 2013}}C++ is a general-purpose programming language with imperative, object-oriented, and generic programming features. Many criticisms have been leveled at C++'s design by well-known software developers including Linus Torvalds,[1] Richard Stallman,[2] Joshua Bloch, Rob Pike,[3] Ken Thompson,[4][5][6] and Donald Knuth.[7][8]

C++ is a multi-paradigm programming language[9] with extensive, but not complete, backward compatibility with C.[10] This article focuses not on C features like pointer arithmetic, operator precedence or preprocessor macros, but on pure C++ features that are often criticized.

Slow compile times

The natural interface between source files in C/C++ are header files. Each time a header file is modified, all source files that include the header file should recompile their code. Header files are slow because they are textual and context-dependent as a consequence of the preprocessor.[11] C only has limited amounts of information in header files, the most important being struct declarations and function prototypes. C++ stores its classes in header files and they are not only exposing their public variables and public functions (like C with its structs and function prototypes) but also their private functions. This forces unnecessary recompiles of all source files that include the header file, each time when changing these private functions. This problem is magnified where the classes are written as templates, forcing all of their code into the slow header files, which is the case with the whole C++ standard library. Large C++ projects can therefore be relatively slow to compile.[12] The problem is largely solved by precompiled headers in modern compilers.

One suggested solution is to use a module system.[13]

Global format state of

C++ unlike C relies on a global format state. This fits very poorly together with exceptions, when a function must interrupt the control flow, after an error, but before resetting the global format state. One fix for this is to use Resource Acquisition Is Initialization (RAII) which is implemented in Boost[14] but is not a part of the C++ Standard Library.

The global state of uses static constructors which causes overhead.[15] Another source of bad performance is the use of std::endl instead of '\' when doing output, because of it calling flush as a side effect. C++ is by default synchronized with which can cause performance problems. Shutting it off can improve performance but forces giving up thread safety.

Here follows an example where an exception interrupts the function before std::cout can be restored from hexadecimal to decimal. The error number in the catch statement will be written out in hexadecimal which probably isn't what one wants:

  1. include
  2. include

int main() {

    try {        std::cout << std::hex;        std::cout << 0xFFFFFFFF << std::endl;        std::vector vector(0xFFFFFFFFFFFFFFFFL,0); // Exception        std::cout << std::dec; // Never reached    } catch(std::exception &e) {        std::cout << "Error number: " << 10 << std::endl; // Not in decimal    }

}

It is acknowledged even by some members of the C++ standards body[16] that the iostreams interface is an aging interface that needs to be replaced eventually. This design forces the library implementers to adopt solutions that impact performance greatly.{{citation needed|date=June 2016}}

Heap allocations in containers

After the inclusion of the STL in C++, its templated containers were promoted while the traditional C arrays were strongly discouraged.[17] One important feature of containers like std::string and std::vector is them having their memory on the heap instead of on the stack like C arrays.[18][19] To stop them from allocating on the heap, one would be forced to write a custom allocator, which isn't standard. Heap allocation is slower than stack allocation which makes claims about the classical C++ containers being "just as fast" as C arrays somewhat untrue.[20][21]{{failed verification|date=June 2016}}{{synthesis inline|date=June 2016}} They are just as fast to use, but not to construct. One way to solve this problem was to introduce stack allocated containers like boost::array[22] or std::array.

As for strings there is the possibility to use SSO (short string optimization) where only strings exceeding a certain size are allocated on the heap. There is however no standard way in C++ for the user to decide this SSO limit and it remains hard coded and implementation specific.[23][24]{{acn|date=June 2016}}

Iterators

The philosophy of the Standard Template Library (STL) embedded in the C++ Standard Library is to use generic algorithms in the form of templates using iterators. Early compilers optimized small objects such as iterators poorly, which Alexander Stepanov characterized as the "abstraction penalty", although modern compilers optimize away such small abstractions well.[25] The interface using pairs of iterators to denote ranges of elements has also been criticized,[26][27] and ranges have been proposed for the C++ standard library.[28]

One big problem is that iterators often deal with heap allocated data in the C++ containers and become invalid if the data is independently moved by the containers. Functions that change the size of the container often invalidate all iterators pointing to it, creating dangerous cases of undefined behavior.[29][30] Here is an example where the iterators in the for loop get invalidated because of the std::string container changing its size on the heap:

  1. include
  2. include

int main() {

    std::string text = "One\Two\Three\Four\";    // Let's add an '!' where we find newlines    for(auto i = text.begin(); i != text.end(); ++i) {        if(*i == '\') {            // i =             text.insert(i,'!')+1;             // Without updating the iterator this program has             // undefined behavior and will likely crash        }    }               std::cout << text;

}

Uniform initialization syntax

The C++11 uniform initialization syntax and std::initializer_list share the same syntax which are triggered differently depending on the internal workings of the classes. If there is a std::initializer_list constructor then this is called. Otherwise the normal constructors are called with the uniform initialization syntax. This can be confusing for beginners and experts alike[31][32]

  1. include
  2. include

int main() {

    int integer1{10}; // int    int integer2(10); // int    std::vector vector1{10,0}; // std::initializer_list    std::vector vector2(10,0); // size_t,int        std::cout << "Will print 10" 

<< std::endl << integer1 << std::endl;

<< std::endl << integer2 << std::endl;

        std::cout << "Will print 10,0," << std::endl;    for(auto &i : vector1) std::cout << i << ',';    std::cout << std::endl;    std::cout << "Will print 0,0,0,0,0,0,0,0,0,0," << std::endl;    for(auto &i : vector2) std::cout << i << ',';

}

Exceptions

There have been concerns that the zero-overhead principle[33] isn't compatible with exceptions.[34] Most modern implementations have a zero performance overhead when exceptions are enabled but not used, but do have an overhead during exception handling and in binary size due to the need to unroll tables. Many compilers support disabling exceptions from the language to save the binary overhead. Exceptions have also been criticized for being unsafe for state-handling, this safety issue has led to the invention of the RAII idiom,{{sfn|Stroustrup|1994|loc=16.5 Resource Management, pp. 388–89}} which has proven useful beyond making C++ exceptions safe.

Strings without Unicode

The C++ Standard Library offers no real support for Unicode. std::basic_string::length will only return the underlying array length which is acceptable when using ASCII or UTF-32 but not when using variable length encodings like UTF-8 or UTF-16. In these encodings, array length is neither a correct measure of the number of code points, number of characters or width. There is no support for advanced Unicode concepts like normalization, surrogate pairs, bidi or conversion between encodings, although unicode libraries exist to handle these issues, such as iconv and ICU.

The example below prints the lengths of two equally long strings. The strings are equally long in characters, but the program takes their lengths in bytes. If the program's source code is saved in a constant width character set like ISO-8859-1, both strings come out as 18 bytes, but in UTF-8, the first string becomes either 22 or 26 bytes depending on unicode normalization.

  1. include
  2. include

int main() {

    // UTF-8 prefix just to be explicit    std::string utf8  = u8"Vår gård på Öland!";    std::string ascii = u8"Var gard pa Oland!";    std::cout << "length of «" << utf8  << "» = " << utf8 .length() << '\';    std::cout << "length of «" << ascii << "» = " << ascii.length() << '\';

}

Code bloat

Some older implementations of C++ have been accused of generating code bloat.[35]{{rp|177}}

See also

{{div col|colwidth=30em}}
  • Most vexing parse
  • Criticism of object-oriented programming
  • Diamond inheritance problem
  • Advantages and disadvantages of templates over macros
  • Function overloading complications
  • Late binding criticism
  • Operator overloading criticism
  • Exception handling criticism
  • Argument dependent name lookup criticism
  • Feature creep
  • Gotcha (programming)
  • Object slicing
{{div col end}}

References

1. ^{{cite mailing list |url=https://lwn.net/Articles/249460/ |title=Re: [RFC] Convert builin-mailinfo.c to use The Better String Library |date=6 September 2007 |accessdate=31 March 2015 }}
2. ^{{cite mailing list |url=http://harmful.cat-v.org/software/c++/rms |title=Re: Efforts to attract more users? |date=12 July 2010 |accessdate=31 March 2015 }}
3. ^{{cite web |url= http://commandcenter.blogspot.mx/2012/06/less-is-exponentially-more.html |title= Less is exponentially more |year= 2012 |last= Pike |first= Rob}}
4. ^{{cite web |url=http://www.drdobbs.com/open-source/interview-with-ken-thompson/229502480 |title=Dr. Dobb's: Interview with Ken Thompson |author=Andrew Binstock |date=18 May 2011 |accessdate=7 February 2014}}
5. ^{{cite book|author=Peter Seibel|title=Coders at Work: Reflections on the Craft of Programming|url=https://books.google.com/books?id=nneBa6-mWfgC&pg=PA475|date=16 September 2009|publisher=Apress|isbn=978-1-4302-1948-4|pages=475–476}}
6. ^https://gigamonkeys.wordpress.com/2009/10/16/coders-c-plus-plus/
7. ^http://www.drdobbs.com/architecture-and-design/an-interview-with-donald-knuth/228700500
8. ^http://tex.loria.fr/litte/knuth-interview
9. ^{{cite web |url=http://www.stroustrup.com/bs_faq.html#multiparadigm|title=What is "multiparadigm programming"?}}
10. ^{{cite web |url=http://www.stroustrup.com/bs_faq.html#remove-from-C++|title=Are there any features you'd like to remove from C++?}}
11. ^{{cite web|url=http://www.drdobbs.com/cpp/c-compilation-speed/228701711|title=C++ compilation speed|author=Walter Bright}}
12. ^{{cite web|url=http://commandcenter.blogspot.de/2012/06/less-is-exponentially-more.html|title=Less is exponentially more|quote=Back around September 2007, I was doing some minor but central work on an enormous Google C++ program, one you've all interacted with, and my compilations were taking about 45 minutes on our huge distributed compile cluster.|author=Rob Pike}}
13. ^{{cite web|url=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4047.pdf|title=A Module System for C++}}
14. ^{{cite web|url=http://www.boost.org/doc/libs/1_60_0/libs/io/doc/ios_state.html|title=iostream state saver}}
15. ^{{cite web|url=http://llvm.org/docs/CodingStandards.html#include-iostream-is-forbidden|title=#include is Forbidden}}
16. ^{{Cite web|url=http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4412.html|title=N4412: Shortcomings of iostreams|website=open-std.org|access-date=2016-05-03}}
17. ^{{cite web|url=http://www.artima.com/intv/goldilocks.html|title=A Conversation with Bjarne Stroustrup}}
18. ^{{cite web|url=http://www.cplusplus.com/reference/vector/vector/|title=std::vector}}
19. ^{{cite web|url=http://www.cplusplus.com/reference/string/string/|title=std::string}}
20. ^{{cite web|url=http://www.artima.com/intv/goldilocks.html|title=A Conversation with Bjarne Stroustrup|quote=I think a better way of approaching C++ is to use some of the standard library facilities. For example, use a vector rather than an array. A vector knows its size. An array does not... Most of these techniques are criticized unfairly for being inefficient. The assumption is that if it is elegant, if it is higher level, it must be slow. It could be slow in a few cases, so deal with those few cases at the lower level, but start at a higher level. In some cases, you simply don't have the overhead. For example, vectors really are as fast as arrays.}}
21. ^{{cite web|url=http://www.stroustrup.com/bs_faq2.html#slow-containers|title=Why are the standard containers so slow?|author=Bjarne Stroustrup|quote=People sometimes worry about the cost of std::vector growing incrementally. I used to worry about that and used reserve() to optimize the growth. After measuring my code and repeatedly having trouble finding the performance benefits of reserve() in real programs, I stopped using it except where it is needed to avoid iterator invalidation (a rare case in my code). Again: measure before you optimize.}}
22. ^{{cite web|url=http://www.boost.org/doc/libs/1_60_0/doc/html/array.html|title=boost::array|quote=As replacement for ordinary arrays, the STL provides class std::vector. However, std::vector<> provides the semantics of dynamic arrays. Thus, it manages data to be able to change the number of elements. This results in some overhead in case only arrays with static size are needed.}}
23. ^{{cite web|url=http://scottmeyers.blogspot.de/2012/04/stdstring-sso-and-move-semantics.html|title=std::string, SSO, and Move Semantics|author=Scott Meyers|quote=Case in point: std::string. It supports moves, but in cases where std::string is implemented using SSO (the small string optimization), small strings are just as expensive to move as to copy! What it means to be "small" is up to the implementation. Unless I'm misreading the source files, std::strings with a capacity of up to 15 are "small" in Visual C++ 11 beta, so std::string objects of up to that capacity will not benefit when copies become moves. (The SSO buffer size seems to be hardwired to be 16 bytes in VC11, so the maximum capacity of a std::wstring that fits in the SSO buffer is smaller: 7 characters.)}}
24. ^{{cite web|url=http://stackoverflow.com/questions/21694302/what-are-the-mechanics-of-short-string-optimization-in-libc|title=What are the mechanics of short string optimization in libc++? A comprehensive answer by Howard Hinnant, libc++ maintainer|author=Howard Hinnant|quote=On a 32 bit machine, 10 chars will fit in the short string. sizeof(string) is 12. On a 64 bit machine, 22 chars will fit in the short string. sizeof(string) is 24. A major design goal was to minimize sizeof(string), while making the internal buffer as large as possible.}}
25. ^{{cite web|url=http://www.open-std.org/jtc1/sc22/wg21/docs/D_3.cpp|title=Stepanov Benchmark|author=Alexander Stepanov|quote=The final number printed by the benchmark is a geometric mean of the performance degradation factors of individual tests. It claims to represent the factor by which you will be punished by your compiler if you attempt to use C++ data abstraction features. I call this number "Abstraction Penalty." As with any benchmark it is hard to prove such a claim; some people told me that it does not represent typical C++ usage. It is, however, a noteworthy fact that majority of the people who so object are responsible for C++ compilers with disproportionately large Abstraction Penalty.}}
26. ^{{cite web|url=http://accu.org/content/conf2009/AndreiAlexandrescu_iterators-must-go.pdf|title=Iterators Must Go|author=Andrei Alexandrescu}}
27. ^{{cite web|url=http://dconf.org/2015/talks/alexandrescu.pdf|title=Generic Programming Must Go|author=Andrei Alexandrescu}}
28. ^{{cite web|url=https://isocpp.org/blog/2014/10/ranges|title=Ranges for the Standard Library|author=Eric Niebler}}
29. ^{{cite book|title=Effective STL|author=Scott Meyers|quote=Given all that allocation, deallocation, copying, and destruction. It should not stun you to learn that these steps can be expensive. Naturally, you don't want to perform them any more frequently than you have to. If that doesn't strike you as natural, perhaps it will when you consider that each time these steps occur, all iterators, pointers, and references into the vector or string are invalidated. That means that the simple act of inserting an element into a vector or string may also require updating other data structures that use iterators, pointers, or references into the vector or string being expanded.}}
30. ^{{cite web|url=http://www.angelikalanger.com/Conferences/Slides/CppInvalidIterators-DevConnections-2002.pdf|title=Invalidation of STL Iterators|author=Angelika Langer}}
31. ^{{cite web|url=http://scottmeyers.blogspot.de/2015/09/thoughts-on-vagaries-of-c-initialization.html|title=Thoughts on the Vagaries of C++ Initialization|author=Scott Meyers}}
32. ^{{cite web|url=http://llvm.org/docs/CodingStandards.html#do-not-use-braced-initializer-lists-to-call-a-constructor|title=Do not use Braced Initializer Lists to Call a Constructor}}
33. ^{{cite web|url=http://www.stroustrup.com/ETAPS-corrected-draft.pdf|title=Foundations of C++|author=Bjarne Stroustrup}}
34. ^{{cite web|url=http://llvm.org/docs/CodingStandards.html#do-not-use-rtti-or-exceptions|title=Do not use RTTI or Exceptions}}
35. ^{{cite book|last=Joyner|first=Ian|title=Objects Unencapsulated: Java, Eiffel, and C++?? (Object and Component Technology)|publisher=Prentice Hall PTR; 1st edition|date=1999|isbn=978-0130142696}}

Works cited

  • {{Cite book | isbn = 0-201-54330-3 | title = The Design and Evolution of C++ | last = Stroustrup | first = Bjarne | authorlink = Bjarne Stroustrup | year = 1994 | publisher = Addison-Wesley | ref = harv}}

Further reading

{{refbegin}}
  • {{cite book|author=Ian Joyner|title=Objects Unencapsulated: Java, Eiffel, and C++?? (Object and Component Technology)|publisher=Prentice Hall PTR; 1st edition|date=1999|isbn=978-0130142696}}
  • {{cite book|author=Peter Seibel|title=Coders at Work: Reflections on the Craft of Programming|publisher=Apress|date=2009|isbn=978-1430219484}}
{{refend}}

External links

  • C++ FQA Lite by Yossi Kreinin
  • C++ The COBOL of the 90s
  • [https://gigamonkeys.wordpress.com/2009/10/16/coders-c-plus-plus/ C++ in Coders at Work] Excerpts from the book Coders at Work, by Peter Seibel
  • DConf 2014: The Last Thing D Needs A video of a talk by Scott Meyers

2 : C++|Criticisms of programming languages

随便看

 

开放百科全书收录14589846条英语、德语、日语等多语种百科知识,基本涵盖了大多数领域的百科知识,是一部内容自由、开放的电子版国际百科全书。

 

Copyright © 2023 OENC.NET All Rights Reserved
京ICP备2021023879号 更新时间:2024/11/12 21:05:25