STL on custom OS - std::list works, but std::vector doesn't - visual-studio-2010

I'm just playing around with a grub-bootable C++ kernel in visual studio 2010.
I've gotten to the point where I have new and delete written and things such as dynamically allocated arrays work. I can use STL lists, for example. I can even sort them, after I wrote a memcpy routine. The problem is when I use the std::vector type. Simply constructing the vector sends the kernel off into la la land.
Obviously I'm missing a function implementation of some kind, but I looked through STL searching for it and came up empty-handed. It fails at the push_back:
vector<int> v;
v.push_back(1);
and disappears into the ether.
Any guesses as to what I'm missing?
Edit yes it's vector of int. Sorry for the confusion. Not only that, but it's not the constructor it fails on, it's a call to push_back.

Stab in the dark: do you have new[] and delete[] implemented? A list will create one item at a time with new while a vector will likely allocate larger blocks of memory with new[].

As per our discussion above, creating a
std::vector<mySimpleStruct> v;
instead of a
std::vector<int> v;
appears to work correctly. This must mean the problem is with something being done in the specialization of some functions for std::vector in your standard template library. I'm assuming you're familiar with template specialization already, but in case you're not:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.7
Also, once you've figured out where the real problem is, could you come back and post the answer here? You have me curious about where the real problem is now, plus the answer may be helpful to others trying to build their own OS kernels.

Do you use a custom allocator or a default one?
You might try using a custom one just to see what allocations vector peforms that might destroy your implementation of the memory manager (this is probably what actually fails).
And yes, please post back once you solve it - it helps all other OSdevers out there.

Related

Why isn't std::move a keyword in C++?

Obviously, move semantics/r-value references were a much needed addition in C++11. One thing that has always bugged me though, is std::move. The purpose of std::move is to transform an l-value into an r-value. And yet, the compiler is perfectly happy to let you continue using that value as an l-value and you get to find out at runtime that you screwed up.
It seems like there is a missed opportunity to define move (or some other name) as a keyword (similar to *_cast) and actually have the compiler understand that the referenced value can no longer be used as an l-value here. I'm sure there is some implementation work to do this, but is there some fundamental reason why this wasn't done?
In C++, moved-from objects in are still objects. They can be used. They are usually in a defined state.
There are some optimizations you can do when you are willing to 'rip the guts' out of an object and use it elsewhere. The C++ committee decided these optimizations should be done implicitly and automatically in a few cases; usually where elision was already permitted, but where it wouldn't work for whatever reason.
Then, the ability to explicitly do this was added. Making this operation end the lifetime of its right hand side would complicate the lifetime rules of C++ to an extreme degree; rather than doing that, they noted they could be highly efficient without complicating the lifetime rules of C++ and leaving them exactly as-is.
It turns out there are a handful of flaws in this; to this extent, C++20 may be adding some "move and destroy the source" operations. In particular, a number of move-construction like operations are easier to write as nothrow if you can both move and destroy the source in one fell swoop.
Actually having it change the lifetime of automatic storage variables is not in the cards. Even describing how such a change would work, let alone making sure it doesn't break anything horribly, would be a challenge.
A simple example of why having it always happen wouldn't be good might be:
Foo foo;
if (some_condition) {
bar = std::move(foo);
}
the lifetime of foo is now a function of some_condition? You'd either have to ban the above with that kind of construct, or go down a pit of madness you may never get out of.

How can I use a Boost Interprocess allocator with a CGAL Nef_polyhedron_3?

There are two types of 3D polys in CGAL, Polyhedron, and Nef_polyhedron. The former allows one to specify an allocator as its fourth template:
http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Polyhedron/Chapter_main.html#Subsection_25.3.5
However, Nef_polyhedron_3 doesn't seem to have that.
What it does have however is iostream operators, to parse to/from an internal string representation:
https://github.ugent.be/divhaere/cgal/blob/master/include/CGAL/Nef_3/SNC_io_parser.h
But that is extremely slow indeed.
Looking at that SNC parser code however, it seems internally it still uses an allocator for its internal structure (an snc object). But even if I could get these to be allocated to my static buffer (to be passed to another process), I can't see anything in the Nef_polyhedron_3 constructors or accessor functions that allows me to reconstruct one.
EDIT: Looking into this a little further, I notice there IS a constructor from an SNC stucture https://github.ugent.be/divhaere/cgal/blob/master/include/CGAL/Nef_polyhedron_3.h :
Nef_polyhedron_3( const SNC_structure& W, SNC_point_locator* _pl,
bool clone_pl,
bool clone_snc) {
And the SNC_structure uses allocators for its internal data (but not for itself):
https://github.ugent.be/divhaere/cgal/blob/master/include/CGAL/Nef_3/SNC_structure.h
Trouble is, that seems to only be set on a compile time basis - I only need to allocate to a specific buffer for polys I know I need to send to another process.
EDIT 2: I just noticed that one of the Nef_polyhedron_3 superclasses is Handle_for:
class Nef_polyhedron_3 : public CGAL::Handle_for< Nef_polyhedron_3_rep<Kernel_, Items_, Mark_> >,
public SNC_const_decorator<SNC_structure<Kernel_,Items_,Mark_> >
In there, that itself uses an allocator too:
https://github.ugent.be/divhaere/cgal/blob/master/include/CGAL/Handle_for.h
I'm still unclear how exactly I plug that in.
Marcos
Nef_polyhedron_3 currently doesn't support custom allocator. However, it is possible to make CGAL use a different allocator through the CGAL_ALLOCATOR macro. However, this will affect all CGAL headers which might be too much. However, it should be possible to add allocator support to the existing code without too much trouble.

net_device and net_device_ops struct

I would like add a new operation at the struct net_device_ops but I am a really newbye in this type of things and I am a bit worried to follow a wrong way from the begin.
I added a ops like this:
static const struct net_device_ops wl_netdev_ops =
{
/* The other operations..
.ndo_clear_stats = clear_stats
};
What is not clear from my point of view is how I can call from user space that, I usually take statisincs from
/sys/class/net/.../statistics
But now I really don't understand where my new operation is placed, can someone help me telling a good tutorial or link where I can find a simple example or tutorial ?
Thanks in advance,
pedr0
Interesting material
You can't call it directly. You need to export its functionality somehow to userspace, e.g. via an ioctl, netlink, a procfs entry, etc. Which one of these is recommended depends largely on what exactly you're trying to achieve.
Usually it's also advised not to change core kernel structures like this, even if you don't plan to distribute your changes - sometimes order of kernel structure members or the size of it matters, and there are assumptions internally in the kernel regarding this. I'm pretty sure there is some other way to do what you want.

What is the difference between Form5!ProgressBar.Max and Form5.ProgressBar.Max?

I'm looking at a piece of very old VB6, and have come across usages such as
Form5!ProgressBar.Max = time_max
and
Form5!ProgressBar.Value = current_time
Perusing the answer to this question here and reading this page here, I deduce that these things mean the same as
Form5.ProgressBar.Max = time_max
Form5.ProgressBar.Value = current_time
but it isn't at all clear that this is the case. Can anyone confirm or deny this, and/or point me at an explanation in words of one syllable?
Yes, Form5!ProgressBar is almost exactly equivalent to Form5.ProgressBar
As far as I can remember there is one difference: the behaviour if the Form5 object does not have a ProgressBar member (i.e. the form does not have a control called ProgressBar). The dot-notation is checked at compile time but the exclamation-mark notation is checked at run time.
Form5.ProgressBar will not compile.
Form5!ProgressBar will compile but will give an error at runtime.
IMHO the dot notation is preferred in VB6, especially when accessing controls. The exclamation mark is only supported for backward-compatibility with very old versions of VB.
The default member of a Form is (indirectly) the Controls collection.
The bang (!) syntax is used for collection access in VB, and in many cases the compiler makes use of it to early bind things that otherwise would be accessed more slowly through late binding.
Far from deprecated, it is often preferable.
However in this case since the default member of Form objects is [_Default] As Object containing a reference to a Controls As Object instance, there is no particular advantage or disadvantage to this syntax over:
Form5("ProgressBar").Value
I agree that in this case however it is better to more directly access the control as a member of the Form as in:
Form5.ProgressBar.Value
Knowing the difference between these is a matter of actually knowing VB. It isn't simply syntactic though, the two "paths" do different things that get to the same result.
Hopefully this answer offers an explanation rather merely invoking voodoo.

What the ugliest API for a relatively well known library that you have seen, and why and how could it be improved? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have been looking at the differences between Lucene 2.9 particular the redone tokenstream API and it just occurs to me its particularly ugly compared to the old just return a new or repopulate the given with values if your reusing said Token.
I have not done any profiling but it seems using a MAP to store attributes is not that efficient and it would be easier to just create a new value type holding values etc. The TokenStream and Attribute stuff looks like object pooling which is pretty much never necessary these days for simple value types like a Token of text.
creat()
When Ken Thompson and Dennis Ritchie received the 1983 Turing Award, after their respective acceptance speeches, someone in the audience asked Ken what he would do differently with Unix if he were to do it all over again. He said, "I'd spell 'creat' with an 'e'."
Livelink (OpenText) API
Everything comes back as some bizarre form of a jagged array
The documentation provides absolutely no examples
[your favorite search engine] typically returns no results for a given API method
The support forums feel near abandoned
The only reliable way of understanding the resultant data is to run the data in the Livelink debugger
And finally... the system costs tens (hundreds) of thousands of dollars
The wall next to my desk has an imprint of my head...
A very simple example of getting a value out of an API method:
var workflow = new LAPI_Workflow(CurrentSession);
// every Livelink method uses an out variable
LLValue outValue;
// every method returns an integer that says if the call was
// a success or not, where 0 = success and any other integer
// is a failure... oh yeah, there is no reference to what any
// of the failure values mean, you have to create your own
// error dictionary.
int result = workflow.ListWorkTasks(workId, subWorkId, taskId, outValue);
if (result = 0)
{
// and now let's traverse through at least 3 different arrays!
string taskName = outValue.toValue(0).toValue("TASKS").toValue(0).toString("TaskName");
}
Aaack!!! :D
I've never been a fan of the java.sql package...
You have to catch the checked exception for everything, and there's only one exception, so it doesn't really give any indication of what went wrong without examining the SQL code String.
Add to that the fact that you have to use java.sql.Date instead of java.util.Data, so you always have to specify the full package for one or the other. Not to mention the conversion that has to take place between the two.
And then there's the parameter index, which is 1-base-indexed instead of the rest of Java, which is 0-base-indexed.
All in all, a pretty annoying library. Thankfully, the Spring library does make it quite a bit easier to work with.
COM. Its biggest improvements ended up being .NET.
Certain java.io.File methods, critical to systems programming, return a boolean to indicate success or failure. If such a method (like, say, mkdir or delete) fails, you have no way at all to find out why.
This always leaves my jaw a-hangin' open.
Java's date/time API is pretty horrible to work with. java.util.Date has several constructors to create an instance for a specific date, but all of them are deprecated. java.util.GregorianCalendar should be used instead, but that has an extremely annoying way of setting fields (think calendar.setField(GregorianCalendar.MONTH, 7) instead of calendar.setMonth(7) which would be far better). The finishing touch is that most other classes and libraries still expect a Date instead of a Calendar, so you have to constantly convert back and forth.
Not not a winner, but deserves a honourably mention; Android. Uses the Java 5 programming language, but barely any of the Java 5 language features. Instead of enums you get integer constants with prefix or suffix.
It can not quite decide if it should be object oriented, or procedural. Showing dialogs being a prime example. Several callbacks with self defined integer ids to display call upon the dialog, that smells of an old C API. And then you get an inner builder class class with chained methods, that smells of over architectured OOP of the worst kind.
The MotionEvent class have X and Y coordinates as absolute and relative values from the same accessory method. But no way to check what kind of coordinates it currently holds.
Android sure is a mixed bag.
I'm going to turn this question on its head and name a beautiful API for a library whose standard API is mostly ugly: the Haskell bindings for OpenGL.
These are the reasons:
Instead of lumping everything into a small number of headers, the library is organized logically into discrete modules, whose contents parallel the structure of the OpenGL specification. This makes browsing the documentation a pleasant experience.
Pairs of "begin/end" functions are replaced by higher-order procedures. For example, instead of
pushMatrix();
doSomeStuff();
doSomeMoreStuff();
popMatrix();
you'd say
preservingMatrix $ do
doSomeStuff
doSomeMoreStuff
The syntax of the bindings enforces the conventions of the library, instead of making you do it by hand. This works for the drawing primitives of quads, triangles, lines, etc. as well. All of this is exception-safe, of course.
Getters and setters are replaced by idiomatic "StateVars", making reading and writing a more symmetric operation.
Multiple versions of functions replaced by polymorphism and extra datatypes. Instead of calling, say, glVertex2f with two float values, you call vertex with a value of type Vertex2 GLFloat.
References:
API Reference
The HaskellWiki page on OpenGL
Beautiful Code, Compelling Evidence (pdf)
Praise from Scott Dillard, quoted in Beautiful Code, Compelling Evidence
Direct3D!
No doubt the old pre-Direct3D 5 interface was pretty darn fugly:
// GL code
glBegin (GL_TRIANGLES);
glVertex (0,0,0);
glVertex (1,1,0);
glVertex (2,0,0);
glEnd ();
// D3D code, tonnes of crap removed
v = &buffer.vertexes[0];
v->x = 0; v->y = 0; v->z = 0;
v++;
v->x = 1; v->y = 1; v->z = 0;
v++;
v->x = 2; v->y = 0; v->z = 0;
c = &buffer.commands;
c->operation = DRAW_TRIANGLE;
c->vertexes[0] = 0;
c->vertexes[1] = 1;
c->vertexes[2] = 2;
IssueExecuteBuffer (buffer);
Its not too bad, nowadays - it only took Microsoft 10 versions to get it right...
I would say MFC, ATL and WTL. All 3 of these libraries use excessive hungarian notation, redefine data types for no apparent reason (CString redefined over and over) and are notoriously changed with each version of visual studio.
I like COM. It provides a component oriented architecture long before .NET was even developed. However, the expansion of COM into DCOM, its many wrappers like ATL and its general lack of comprehensive documentation make it the ugliest API i have to deal with at work.
Most certainly not the ugliest. There are probably so many, but Flex has a special place in hell. Specifically UIComponent which compared to the Sprite, feels like using a chainsaw to peel an apple. I believe Flex would have been much improved by using more lightweight objects and mixin-style features similar to how Dojo works on the Javascript side.
The ECMAScript/Actionscript Date class is all but backwards and useless. It's been a constant pain any time I've needed to do something more complex than add timestamps to logs. They need more parsing options (e.g., the ability to specify the input format), and better time management, like intelligent increments, convenience functions, etc...
C++ STL libraries (and templates in general), while obviously useful, have always felt plain ugly. No suggestions for improvements though. They work.
Oracle's ProC, ProAda, Pro*this-that-the-other things. They were a preprocessor front end for C, Ada, and Fortran, I think, maybe some others, that let you jam SQL into your source code.
They did also have a library which worked much better, and was much more flexible.
(That was more than 10 years ago, I have no idea what they do now, though I wouldn't be surprised if it was still the same, just so as not to break people's code.)
well, it was a well-known library about 20 years ago, but i think the original btrieve data engine has the worst api ever written. almost everything goes through a single call, with each of its many parameters containing a different value depending on which call you're really doing (one parameter was a flag telling the system if you wanted to open a file, close a file, search, insert, etc). i liked btrieve way back then, but i spent a long time making a good abstraction layer.
it could have been easily improved by not forcing everything into one call. not only was the one call hideous, but the programmer was responsible for allocating, passing in, and freeing the position block ... some memory used by btrieve to track the open file handle, position, etc. another improvement would be to allow ascii text to be used when defining the indexing. indices had to be specified by a convoluted binary representation.
best regards,
don
A lot of the CRT library functions are poorly or vaguely named possibly due to legacy coding restrictions back in the day and thus require frequent use of the F1 key for people to find the right function and supply the right arguments.
I've been using CRT functions for a while and I still find myself hitting F1 a fair amount.

Resources