What is a pure-C alternative to STL containers? [duplicate] - c++

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.

Related

Boost..... what is all the fuss about? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
For a long time being a Java programmer and only hearing boost mentioned I thought it was so favoured because the Standard C++ language doesn't have any mechanism for threading. However, I then stumbled on the fact that there are libraries one can use on linux for threading. Therefore I am a little puzzled why the boost libraries are so popular?
From the perspective of someone deciding which parts of boost to get "stuck in" and learn, could programmers who use it please explain why it is so popular and the most favoured parts from the point of view of recruiters (preferably financial development)?
To make this more Stackoverflow-friendly, what are the libraries/features which make boost what it is?
I thought it was so favoured because the Standard C++ language doesn't have any mechanism for threading. However, I then stumbled on the fact that there are libraries one can use on linux for threading.
That's odd reasoning. There is a lot more to Boost than threading. Plus, just because there's a Linux library for threading doesn't mean it will work on your Windows code; Boost.Thread is cross-platform.
Allow me to hit some of the high points of Boost:
Smart Pointers
C++11 now has most of these (and improvements on them using C++11 language features). But for the past 8+ years, this was where you came for a good shared_ptr implementation. Use of these things should be mandatory where possible.
They make life in C++ so much simpler.
Regex
Not my cup of tea, and another Boost library incorporated into C++11. But if you want to do regular expression searching of strings, it doesn't get much more standard than this.
Bind and Function
Yet another thing that was incorporated into C++11, but unless you have access to a C++11 compiler/library, Boost is your best bet for this. Being able to store any kind of "callable" object in an object is incredibly useful for callbacks. And being able to adapt "callable" objects to different sets of parameters is incredibly useful, particularly with algorithms.
Filesystem
C++ has standard library facilities for opening and closing files. But nothing for looking for them or dealing with filenames. Boost does, and in a very nice API to boot. It handles platform-specific encoding through a platform-neutral interface. It allows Unicode support across those platforms that have it, etc.
Range
You know how the standard algorithms take a begin and end iterator, but most of the time you really just want it to walk the whole container? Range is here for you. It defines iterator ranges (which containers are), and it provides algorithm variants that take range objects explicitly.
What's great about Range is that the range algorithms are lazily evaluated. So you can do functional-style composition of algorithms, which works efficiently. Many algorithms return a range (which is really a range placeholder); if you feed one range into another range, you can get powerful effects with simple composition.
Variant
AKA: a type-safe union. Once you put an object of type X into it, you cannot get anything but type X out of it. Period. This is a useful tool for doing some light runtime-polymorphism work without having to use a derived class.
These are just a few of the libraries in Boost.
Boost is in part, a staging arena for proposals for the standard template library. It has strong threads solutions. However, boost also provides a wide range of other things such as containers, expression parsers... It is famous because it is a central repository for C++ non-standard libraries.
These are the libraries/features which make boost what it is. Threading is not the only thing you want to do in an application... The most "favored" depends on what you are programming, all of the libraries are useful, otherwise it would be unlikely to have been included.
Boost is just a big non-standard library collection.
C++'s STL is getting better and better, yet it's not nearly as huge as Boost (and is not intended to).
Think of Boost as a collection of useful libraries (for various purposes from math thru parsers thru containers to metaprogramming, see the docs for the list) which is known to be of good quality and just happens to be packaged together.
"boost" is just a repository of high quality C++ libs. If you write a good C++ library useful for a lot of people and which meets boost quality standard, you can ask it to be added to boost.
It happened that influent C++ programmers who are working on the C++ standards are also writers of some boost libs. Some boost libs are now standard. That makes it a central place for the C++ community.
Concerning your question about threads, boost would offer portability over using a linux-only thread lib. The boost version works on windows, too.
As a Java program you're probably used to having classes available at your fingerprints for doing a wide variety of things, from threading to XML parsing to logging to regular expressions.
The C++ core language is sparse in this regard compared to most other languages. We've got containers and algorithms, but not a lot else. Boost fills some of the gap between C++ and other languages in terms of ready-made and test libraries that we can import and useo right away rather than spend time reinventing them.
In C++11, some of the best libraries in Boost (Regex, Unordered Cntainers, Smart Ptr to name a few) are becoming part of the language. That isn't a coincidence, it's a direct result of their popularity and maturity as part of Boost.
In terms of what is most attractive, I would say a cursory familiarity with every library would be most important. Be able to say "Yes I've used boost" and "Boost.Widget" would be a good fit for this problem. Most everything else is just API reference.
If I had to pick one: Boost.Asio has definitely changed the way I think about networking. (And it's use of shared_from_this() and Smart Ptr show me new ways to think about memory management. Sorry, I guess that's two.)

C++ STL low level programming

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.

Have I used STL? Or not?

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?

Reason for not using the STL? [duplicate]

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.

Why STL containers are preferred over MFC containers?

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.)