Is it possible to do some low level programming with STL, at least containers and algorithms? I need to do a simple OS and have to know if is feasible to try the C++ and STL or go with plain C. Any resources are accepted.Thanks.
Edit---------
And how about Boost?
Most implementations of the C++ STL I'm familiar with have been significantly dependent on an OS (particularly for memory allocation). I'm not going to rule out using the C++ STL in an operating system kernel, but you'd have to do a lot of work to port an implementation of the STL to your environment (e.g, implement a memory allocator, make exception handling work, write an iostreams compatibility shim to output to the screen/TTY/whatever), and to get a compiler to target your implementation correctly. It may be less work overall to just write the OS in C. :)
You should totally use the C++ STL. Even if you only work with bare pointers and arrays, the STL Algorithms will vastly clarify your thinking and programming. The genius of Alexander Stepanov's STL is that Algorithms are expressed with respect to Iterators, and Iterators are a generalization of pointers, so you can apply any of his algorithms to raw pointers and arrays with zero run-time overheard.
Plus, here's the best part. If you think like Alexander Stepanov, and use his pointer-to-beginning and pointer-to-past-the-end idiom, all of the plus one (+ 1) and minus one (- 1) terms will drop out of your array and loop logic and you'll never again have to watch out for off-by-one logic errors.
You should write an OS that natively represents strings as a pair of byte* to begin and past-the-end of a UTF8 memory block. Then your OS can replace the Unices and liberate us from null-terminated signed char* strings.
You can (and should) use C++ for an OS. Depending on where in the OS
the code occurs, you might have to forgo parts (or all) of the standard
library, and in some cases perhaps, even some functionality
(exceptions?); it all depends on the context.
With regards to the STL containers, they would certainly be usable at
some levels, provided you specify custom allocators. (The library
implementation of operator new will depend on OS functionality, so
probably won't be available in the OS itself. Although even this
depends on the design of the OS.) And there should be no problem with
most of the algorithms.
Related
When would I need an alternative to C++'s STL?
Are there any advantages to using an alternative STL?
Which ones would you recommend, if any?
Sorry for these noob bullet points, but I see a lot of products that ship with different STLs linked in and was wondering when something like that is useful.
I'm assuming you're talking about alternative implementations of STL, rather than alternatives to the STL.
There's a few reasons you might use a 3rd party STL implementation, rather than the default one provided by your compiler.
Consistency - you might be using multiple compilers and want to ensure you get the same behavior on each platform.
Speed - An implementation might be more efficient than the one provided by your compiler.
Completeness - Your compilers default library might not provide the full complement of STL features. (This may only be for old compilers, or compilers for embedded systems, or for C++11 features).
Extra features - Some implementations of STL provide features like improved debugging of invalid iterators etc, which may not be in your compilers implementation.
Obviously not all these hold for all compilers .. but there are certainly cases where 3rd party STLs can be helpful.
As for implementations: you can find a list here
Michael's provided a good answer - just a couple points to add:
"Speed" isn't just a linear thing where you can say decisively that STL implementation X is N% faster than STL Y: there are implementation choices trading off speed and memory usage in various usage scenarios. For example, a "short string optimisation" may allow very short strings to be stored directly in the string object rather than in heap memory; implementations may have slightly different choices about how generously to resize containers exceeding their current capacity.
Binary interoperability is a big deal: if you need to call a library function that's pre-compiled to accept STL X objects, you can't simply link the library and feed it the STL Y equivalents: there could be differences in the mangled names preventing linking, the binary layout of the objects may well be different, and even if not and you forced such a call - the operations your client code performs on those objects may not be be everything the library code expects or needs (i.e. wouldn't maintain the same invariants).
Thread safety is a noteworthy example of "extra features"... e.g. many early STLs had errors with Copy-on-Write string implementations.
Another point: some STL implementations allow you to disable the use of exceptions, possibly using a custom global error handler instead of C++ exceptions. This is less important nowadays, but for a long time, a lot of systems had exceptions disabled for various reasons, and there are still a few outlier systems on which exceptions are discouraged or completely unsupported.
I'm confused about some of the documentation at cplusplus.com. Have I used the standard template library with either of these two lines of code?
for (std::string::const_iterator it = str.begin(); l < data.size; ++it, ++l)
and
tile_tag(): distance(std::numeric_limits<int>::max()), dir(unknown_direction), used(false)
See:
http://www.cplusplus.com/reference/string/string/begin/
and
http://www.cplusplus.com/reference/std/limits/numeric_limits/
If I have used STL, how can I modify them to do what they do without STL?
Thanks!
EDIT: I guess this is OUR definition of STL: http://www.sgi.com/tech/stl/stl_index_cat.html
I don't see const_iterator...but I do see max. But is that the max I used?
Yes, you used it, since std::string alone is "part of the STL", but, more importantly, you are using the iterators, which are a distinctive trait of the STL.
Now, for the mandatory purists part: the STL was a library published by SGI and developed mainly by Alexander Stepanov. What I think you are referring to is "the part of the SGI STL which was later included into the standard with some minor modifications", i.e. all the generic containers/algorithms/iterators stuff.
The usage of the term "STL" for this stuff is tolerated, what is plain wrong, instead, is calling "STL" the whole C++ standard library (which includes a lot of other stuff, e.g. iostreams, locale, the library inherited from C, ...).
If I have used STL, how can I modify them to do what they do without STL?
Why would you want to do that? Anyhow, you have several options, that span from rewriting such classes and algorithms from scratch to using simpler data structures (e.g. C strings) reimplementing only the algorithms you need. Anyway, they both imply reinventing the wheel (and probably reinventing a square wheel), so I'd advise you against doing this unless you have a compelling reason.
EDIT: I guess this is OUR definition of STL: http://www.sgi.com/tech/stl/stl_index_cat.html
Are you sure? Almost no one today uses the SGI STL, generally you use the (more or less) equivalent portion of your C++ standard library (that, by the way, is what you are doing in your code, since you are getting everything from the std namespace).
I don't see const_iterator...
const_iterator is a typedef member of basic_string<char>, you find it in its page.
but I do see max. But is that the max I used?
No, it's not it, your max is not a global function, but a member of the std::numeric_limits template class. Such class do not come from the STL.
Does your code include the namespace std? Then yes, you have used the Standard library. How you can you modify your code to not use the Standard library? Why on earth would you want to? Implementations must provide it- that's why it's called Standard. But if you're truly insane and feel the need to not use it, then ... look up the documentation on what those functions and classes do and write your own replacement.
You have used the STL std::string and std::numeric_limits. I don't know why you would want to avoid using STL (perhaps homework?). You could use old style C strings with a char* and the macro definition MAX_INT from C limits.
What is this "STL" you speak of?
There was this thing that SGI developed in the mid 90s. Yeah, that's 15+ years ago. Older than the previous C++ standard. Back in the days when compilers like Turbo C++ and Borland C++ were best-of-breed; when people used the phrase "C with classes" unironically and without derision; when the idea of compiling C++ primarily by first cross-compiling to C was finally being abandoned; when exceptions were (at least in this context!) a new idea.
They called it "STL" for "standard template library", and they were doing a bunch of neat things with templates and developing new idioms. For its time, it was pretty revolutionary. So much so, in fact, that almost all of its stuff got officially accepted into the standard library with the 1999 standardization of the language. (Similarly, lots of Boost stuff - although nowhere near all; Boost is huge - has been added to the std namespace in the new standard.)
And that's where it died.
Unless you are specifically referring to a few oddball things like std::iota or lexicographical_compare_3way, it is not appropriate to speak of "the STL", and it hasn't been appropriate to speak of "the STL" for twelve years. That's an eternity in computer science terms. (But, hell, I still seem to keep hearing about new installations of Visual C++ 6.0, and some people using even older compilers...)
You're using the standard library of the C++ language. I guess you could write "SC++L" if you like, but that's a bit awkward, isn't it? I mean, no sane Java programmer would ever refer to the SJL, nor any Pythonista to the SPL. Why would you need jargon to talk about using the standard library of the language you are using?
This is what you're supposed to do by default, after all. Could you imagine writing code in C without malloc, strlen et. al.? Avoiding std::string in C++ would be just as silly. Sure, maybe you want to use C++ as a systems programming language. But really, the kinds of applications where you absolutely have to squeeze out every cycle (keep in mind that using std::string is often more efficient than naive string algorithms, and difficult to beat with hard work, because of the simple algorithmic benefits of caching the string length count and possibly over-allocating memory or keeping a cache for short strings) are generally not ones that involve string processing.
(Take it from me - I have several years' experience as a professional mobile game developer, dating to when phones were much, much less powerful: the standard approach to string processing is to redesign everything to need as little of it as possible. And even when you do have to assemble - and line-wrap - text, it was usually not worth optimizing anyway because the time the code spends on that is dwarfed by the time it takes to actually blit the characters to screen.)
"STL" can mean a number of things.
Formally, the name "STL" was only ever used for the library developed by Stepanov, and which is now hosted by SGI. The library consisted, roughly speaking, of containers (vector, list, deque, map, set and all those), iterators and algorithms (and a few other bits and pieces, such as allocators)
This library was adopted and adapted into the C++ standard library when the language was standardized in 1998. In this process, a number of changes were made: corners were cut, components were left out, in order to keep the library small, and to make it easy to swallow for the committee members. A number of changes in order for it to better interoperate with the rest of the standard library, or with the language itself, and certain parts of the existing standard library were modified to become a bit more STL-like.
Today, it's really not very useful to discuss the original STL. So when most C++ developers say "STL", they mean "the part of the C++ standard library that was created when the STL was adopted into the standard". In other words, all the container classes, the iterators and the algorithms in the standard library, are commonly called "STL", simply because they look a lot like the "original" STL, and they're a lot more relevant today than the original library.
But this also means that the term has become rather fluffy and vague. The std::string class was not a part of the original STL. But it was modifed to behave "STL-like". For example, it was given iterators, so that it can be used with the STL algorithms. Should it be considered a part of the STL? Maybe, maybe not.
And to forther confuse matters, the STL became fashionable after it was adopted into the language. Suddenly, people started talking about "STL-style". The Boost libraries, for example, are generally written in a very STL-like way, and some Boost libs have been adopted into the standard library in C++11. So should they now be considered part of the STL?
Probably not, but you could make a pretty good case that they should: that they follow the spirit of the STL, and if Stepanov had thought of them when he write the original STL library, maybe he'd have included them.
Except for a few purists, who think that everyone is better off if the term "STL" is used exclusively to refer to something that no one ever actually needs to refer to (the SGI library), and if we have no way to refer to the standard library subset that it spawned, pretty much any C++ developer can agree that if you've used the standard library containers OR the standard library iterators OR the standard library algorithms, then you have used the STL.
In your code I see an iterator. So yes, you've used at least a small corner of the STL.
But why does it matter?
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Container Class / Library for C
One of the primary reasons to use C++ over C is the superbly convenient containers that STL provides. However, if I want to write my code in pure C and not have to write all my containers from scratch, what alternative do I have ?
Some of the ones that I have heard of (but never used) are
Glib
iMatix Standard Function Library
disparate elements from the Linux kernel headers (e.g. list)
Any opinions and/or experiences with containers in pure C (Ansi or otherwise) would be much appreciated.
I'd recommend GLib solely because it's got a nice set of features and it's relatively mature, stable, portable, and widely used.
You, or a library writer, can write containers etc. each time you want to use them for a different type, possibly putting definitions into gigantic macros, or you can use void * for containers, losing all hope of type safety and sometimes some performance. (C's qsort function can be significantly less efficient than C++'s sort template.) There is no way to get the equivalent of C++ containers, iterators, and algorithms in C.
I don't know much about Glib, and your reference to disparate elements from Linux kernel headers is a little vague. The Linux list you mention is probably typical of what you'd get: no type safety and a set of well-written functions that will be named differently for each data type. A quick look at iMatix didn't disclose any containers.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
To STL or !STL, that is the question
Are there cases where one should avoid the use of the C++ STL in his / her project?
When you choose to use a framework like Qt you might consider using lists, vectors, etc from Qt rather that the STL. Not using STL in this case saves you from having to convert from STL to the Qt equivalents when you need to use them in your GUI.
This is debatable and not everyone wants to use everything from Qt
from http://doc.qt.nokia.com/latest/containers.html
These container classes are designed to be lighter, safer, and easier to use than the STL containers. If you are unfamiliar with the STL, or prefer to do things the "Qt way", you can use these classes instead of the STL classes.
If you cannot use RTTI and/or exceptions, you might experience that parts of STL won't work. This is the case e.g. for native Android apps. So if it doesn't give you what you need, it's a reason not to use it!
Not really. There's no excuse to ban the use of an entire library- unless that lib only serves one function, which is not the case with the Standard library. The provided facilities should be evaluated on a per-function basis- for example, you may well argue that you need a container that performs a more specific purpose than vector, but that is no excuse to ban the use of deque, iostream or for_each too.
More importantly, code generated via template will not be more bloated than the equivalent code written by hand. You won't save code bloat by refusing to use std::vector and then writing your equivalent vector for float and double. Especially in 2011, the size of an executable is pretty meaningless compared to the sizes of other things like media in the vast, vast majority of situations.
If you care a lot about executable size, then you might want to avoid using STL in your program.
For example, uTorrent doesn't use STL and that is one reason why it's so small.
Since STL does rely on templates a lot (it is Standard TEMPLATE Library, after all), many times you use templates, the compiler has to generate extra code for every type you use when dealing with STL.
This is compile time polymorphism and will increase your executable size the more you use it.
If you exclude STL from your project (and use templates sparingly or not at all), your code size will get smaller. Note that it won't necessarily be faster.
Also note that I'm not talking about a program's memory usage during execution, since that will depend on how many objects your allocating during your app's lifetime.
I'm talking about your binary's executable.
If you want an example, note that a simple Hello world program, when compiled, might be bigger than a cleverly code demo which can include an entire 3D engine (run time generated) in a very small executable.
Some info regarding uTorrent's size:
Official FAQ (from 2008), this question doesn't appear in recent FAQ.
How was uTorrent programmed to be so efficient?
Second post regarding this.
Third post regarding this.
Note that, even though uTorrent is >300kb and is compressed with UPX, it is still really small when you take into account what it's capable of doing.
I would say that there may be occasions where you do not use a particular feature of STL in your project for a given circumstance because you can custom write it better for your needs. STL collections are generic by nature.
You might want in your code:
Lock-free containers that are thread-safe. (STL ones are not).
A string class that is immutable by nature and copies the actual data "by reference" (with some mechanism).
An efficient string-building class that is not ostringstream (not part of STL anyway but you may mean all the standard library)
algorithms that use Map and Reduce (not to be confused with std::map. Map and Reduce is a way to iterate over a collection using multiple threads or processes, possibly even distributed on different machines).
Hey, look, so much of boost was written because what the Standard Library provided at the time did not really address the needs of the programmer and thus provided alternatives.
I am not sure if this is what you meant or if you particular meant STL should be "banned" at all times (eg device driver programming where templates are considered bloaty even though that is not always the case).
If you are working to particular standards that forbid it.
For example, the MISRA C/C++ guidelines are aimed at automotive and embedded systems and forbid using dynamic memory allocation, so you might choose to avoid STL containers altogether.
Note: The MISRA guideline is just an example of a standard that might influence your choice to use STL. That particular guideline doesn't rule out using all of the STL. But (I believe) it rules out using STL containers as they rely on runtime allocation of memory.
It can increase executable size. if you're running on an embedded platform you may wish to exclude the STL.
When you use something like the Qt library that implements identical functionality you may not need the STL. May depend on other needs, like performance.
The only reason is if you are working on embedded systems with low memory, or if your project coding guidelines explicitly forbid STL.
I can't other reasonable reason to manually roll your own incompatible, bug ridden implementation of some of the features on STL.
TR18015 deals with some of the limitation of the STL. It looks at it from a different angle - what compilers could do better - but still is an interesting (if in-depth) read.
I'd be careful in general with microprocessors and small embedded systems. First, compiler optimizations are not up to what you know from desktops, and you run into hardware limits much sooner.
Having said that, it depends a lot on the libraries you use. I/O streams are notoriously slow (and require a careful implementation to not be), whereas std::vector is merely a thin wrapper.
Previously, I used to use MFC collection classes such CArray and CMap. After a while I switched to STL containers and have been using them for a while. Although I find STL much better, I am unable to pin point the exact reasons for it. Some of the reasoning such as :
It requires MFC: does not hold because other parts of my program uses MFC
It is platform dependent: does not hold because I run my application only on windows.(No need for portability)
It is defined in the C++ standard: OK, but MFC containers still work
The only reason I could come up is that I can use algorithms on the containers. Is there any other reason that I am missing here - what makes STL containers better than MFC containers?
Ronald Laeremans, VC++ Product Unit Manager, even said to use STL in June 2006:
And frankly the team will give you the same answer. The MFC collection classes are only there for backwards compatibility. C++ has a standard for collection classes and that is the Standards C++ Library. There is no technical drawback for using any of the standard library in an MFC application.
We do not plan on making significant changes in this area.
Ronald LaeremansActing Product Unit ManagerVisual C++ Team
However, at one point where I was working on some code that ran during the installation phase of Windows, I was not permitted to use STL containers, but was told to use ATL containers instead (actually CString in particular, which I guess isn't really a container). The explanation was that the STL containers had dependecies on runtime bits that might not actually be available at the time the code had to execute, while those problems didn't exist for the ATL collections. This is a rather special scenario that shouldn't affect 99% of the code out there.
STL containers:
Have performance guarantees
Can be used in STL algorithms which also have performance guarantees
Can be leveraged by third-party C++ libraries like Boost
Are standard, and likely to outlive proprietary solutions
Encourage generic programming of algorithms and data structures. If you write new algorithms and data structures that conform to STL you can leverage what STL already provides at no cost.
Compatibility with other libraries (such as boost) in syntax, interoperability, and paradigm. It's a non-trivial benefit.
Using STL will develop a skillset that is more likely to be useful in other contexts. MFC isn't so widely used any more; STL is.
Using STL will develop a mindset that you may (or may not) find useful in code you write yourself.
Using something other than STL isn't inherently wrong though.
STL has more collection types than MFC
Visual Studio (2008+) debugger visualizes STL much better than MFC. (AUTOEXP.DAT magic can fix that - but it is a pain! Nothing like debugging your debugger when you screw it up...)
One good thing with MFC is that there is still a large corpus of MFC code out there. Other answers talk about third-party compatibility. Don't forget third party MFC-based stuff.
I always prefer using more standard/compatible libraries where I can since I may have future projects that I can reuse a portion of the code on. I have no idea what libraries future projects will use, but I have a better chance of making my code reusable if I use standard/compatible stuff.
Also, the more I use a library, I get more comfortable and quicker with it. If I am going to invest the time to learn a library, I want to make sure it's going to stay around and is not tied in with a specific platform or framework.
Of course, I say all of this assuming that my choices are rather similar when it comes to performance, features and ease of use. For instance, if the MFC classes are a significant enough improvement in these areas, I would use them instead.
In fact you can use STL algorithms on some of MFC containers as well. However, STL containers are preferred for another very practical reason: many third-party libraries (Boost, arabica, Crypto++, utf-cpp...) are designed to work with STL, but know nothing about MFC containers.
MFC containers derive from CObject and CObject has the assignment operator made private. I have found this very annoying in practice.
std::vector, unlinke CArray, guarantees that the memory block is contiguous, thus you can interop with C programming interfaces easily:
std::vector<char> buffer;
char* c_buffer = &*buffer.begin();
It is now assumed that C++ developers are at least passingly familiar with the STL. Not so for MFC containers. So if you're adding a new developer to your team, you will have an easier time finding one who know STL than the MFC containers, and thus will be able to contribute immediately.
I think it boils down to a simple question: Who do you trust more? If you trust Microsoft, then continue to use the MFC variants. If you trust the industry, then use STL.
I vote for STL because the code that runs on Windows today might need to be ported to another platform tomorrow. :)
This is a case of whichever tools work for the job you want to do, and 'better' being a subjective term.
If you need to use your containers with other standards-compliant code, or if it is ever going to be code that is shared across platforms, STL containers are probably a better bet.
If you're certain that your code will remain in MFC-land, and MFC containers work for you, why not continue to use them?
STL containers aren't inherently better than MFC containers, however as they are part of the standard they are more useful in a wider range of contexts.
Next to the mentioned aspects: well-supported, standard available, optimized for performance, designed for use with the algorithms, I might add one more aspect: type-safety, and loads of compile-time checks. You can't even imagine drawing a double out of a std::set<int>.
Because a library that uses iterators to combine sequences of any kind with algorithms so that A) all sensible permutations are possible and B) it's universally extensible, is (when you think about your concept of a container library as it was 15 years ago) such a mind-blowingly marvelous idea, that it has pretty much blown out of the water everything else within less than a decade?
Seriously, the STL has its flaws (why not ranges instead of iterators? and that erase-remove idiom is not exactly pretty), but it's based on a brilliant idea and there's very good reasons we don't need to learn a new container/algorithms library every time we start at a new job.
I wouldn't totally dismiss the portability argument. Just because you use MFC today doesn't mean that you always will. And even if you mostly write for MFC, some of your code could be re-used in other applications if it were more generic and standards-based.
I think the other reason to consider STL is that its design and evolution has benefited from libraries that have come before, include MFC and ATL. So many of the solutions are cleaner, more re-usable, and less error prone. (Though I wish they had a better naming convention.)