I'm currently reading an unreleased master thesis report, that I'm going to give feedback on.
In the report they mention Garbage Collector under native C++ and managed C++. I thought C++ didn't have any standard GC, am I wrong or right? (They do not mention Boehm-Demers-Weiser.)
They have some problem getting it to work under some conditions. They create objects in one thread, and then delete the pointer from another thread.
Native C++ by default has no such thing (the closest thing to this are the smart pointers, but that's still something entirely different), but that doesn't prevent you from writing your own garbage collection solution (or using third party solution).
Managed C++ (and its successor C++/CLI) of course use .NET garbage collection for managed resources (though native resources are not garbage collected and have to be managed manually as in native C++).
Existing C++ standard of 1998/2004 does not specify a garbage collector.
The upcoming standard C++0x does specify an optional garbage collector API, however the implementation is an other part.
With all that said, there are garbage collectors available for C++ from compiler vendors and third party.
GCC suite provides Boehm-GC for garbage collection.
Managed C++ was Microsoft's extension to C++ released with .Net 1.0 which extended C++ with garbage collection capabilities.
There is also C++/CIL from Microsoft released with .Net 2 which deprecated Managed C++ with more .Net centric features.
Sun Provided libgc as garbage collector for C/C++.
The only GC library for C and C++ is Hans-Boehm library, but as far as I know it is difficult to set it.
I have a different take on GC under C++.
Have a look at MCP (open source license GPLv3) -- GC with C++ should not have to be any worse than GJC / Mono.
Related
Let me clarify what I mean by 'normal' C++ first- I'm currently reading Walter Savitch's "Problem Solving in C++". As far as I am aware this is not written specifically for Microsoft or Unix. So my question is, how does what I am learning in this book (which I am using for my universal knowledge-gaining of c++) differ from what I keep reading about CLI C++?
Is CLI C++ just what I would encounter if I used Visual C++? I'm totally confused.
C++/CLI, (Also sometimes C++/CLR) refers to a language which is positioned somewhere in between native C++, and the .NET framework.
It's usually used for applications where you need to bridge some native code (pure C++) and managed code (Like VB, C#, F#, etc).
C++/CLI is a much different beast than regular C++ though. And when people say Visual C++, the meaning can vary depending on context. Sometimes they mean C++ with the common language runtime (CLR) layer enabled, other times they mean just plain C++. It's unfortunate that there's a lot of different terminology out there, and a lot of misnomers, but what can you do?
C++ and C++/CLI differ greatly. C++/CLI is the managed .NET-version of C++, made by Microsoft to enable a layer from .NET to native code.
c++/cli is the current version of Microsoft's Visual c++ brand of tools. (There was a different design before c++/cli)
c++/cli is really two versions of c++ in one. There is a highly standardized c++ compiler and also a version of c++ that runs on the CLI virtual machine. Obviously standard c++ never runs on a VM so that determined the two in one approach to the language.
When using it you can mix unman aged and managed code together. "Unmanaged" is code compiled just like standard c++. "Managed" is code compiler to the CLI (.Net) virtually machine's bytecode. Microsoft has extensive APIs for both managed and unmanaged code. With the product you can access both APIs.
You can develop standard c++ apps with the language and tool, you just have to be careful not to used the non-standard extensions. I suggest compiling in another compiler once in a while if you are in doubt. The managed side is totally non standard and even the unmanaged side has tons of non standard extensions.
PS I'm no expert but I was curious and read about this last week. I thought your question deserved an answer. Good luck!
Is it possible to use SGen garbage collector (from the mono runtime) in coventionnal C/C++ programs ?
I think mono used also the Boehm-Demers-Weiser conservative garbage collector that can be used in C/C++ programs.
There are very few dependencies on the rest of the Mono code in SGen, so it should be easy to extract it out and adapt to other uses.
The major difference from the Boehm collector is that it currently doesn't support a non-precise mode for heap objects, so you can't use it to replace malloc easily.
It would work great, though, for managing objects for which you could provide precise reference information.
Not sure about the garbage collector that you have specified. But do you really need to use a GC on a C++ project? I never felt the use of a GC in my C++ projects. You should be good if you follow the best practices and use a decent smart pointer.
I've been given some Symbian C++ code to port over for use with the Android NDK.
The code has lots of Symbian specific code in it and I have very little experience of C++ so its not going very well.
The main thing that is slowing me down is trying to figure out the alternatives to use in normal C++ for the Symbian specific code.
At the minute the compiler is throwing out all sorts of errors for unrecognised types.
From my recent research these are the types that I believe are Symbian specific:
TInt, TBool, TDesc8, RSocket, TInetAddress, TBuf, HBufc,
RPointerArray
Changing TInt and TBool to int and bool respectively works in the compiler but I am unsure what to use for the other types?
Can anyone help me out with them? Especially TDesc, TBuf, HBuf and RPointerArray.
Also Symbian has a two phase contructor using
NewL
and
NewLc
But would changing this to a normal C++ constructor be ok?
Finally Symbian uses the clean up stack to help eliminate memory leaks I believe, would removing the clean up stack code be acceptable, I presume it should be replaced with try/catch statements?
I'm not sure whether you're still interested, but one possibility is that where the Symbian idioms are using the EUSER.DLL (i.e. TDesC derived classes, RPointer*, etc) you may find taking the open source EPL code from Symbian developer site and adding it directly into your port a viable option. That is port over the necessary bits of EUSER (and others perhaps?).
However, if your current code base already uses a lot of the other subsystems you're going to see this become very unwieldy.
You should try to read some introductory text on development for Symbian. They used to have some examples in the Symbian site, and I am sure that you can find specific docs on how the types you want are meant to be used and what they provide.
The problem is that symbian development has its own idioms that cannot/should not be directly used outside of the symbian environment, as for example the two phase construction with the cleanup stack is unneeded in environments where the compiler has proper exception handling mechanisms --in Symbian a constructor that throws can lead to all sorts of mayhem.
If this is not a very large codebase it may be easier/faster to start from scratch and doing everything Android style. Even if you require NDK/C++ this approach may be quicker.
Another approach may be to use portable C/C++ for the core, and the use this on both Symbian and Android version while doing UI stuff separately for each platform. Spotify have done this on Android and iPhone.
It would typically be a bad idea to try and port Symbian OS C++ to standard C++ without having a very good understanding of what the Symbian idioms do.
This could very well be one of these projects where the right thing to do is to rewrite most of the code pretty much from scratch. If you barely know the language you are targetting, there is little point in deluding yourself into thinking you won't make mistakes, waste time and throw away new code anyway. It's all part of learning.
The CleanupStack mechanism is meant to help you deal with anything that could go wrong, including power outage and out of memory conditions. Technically, these days, it is implemented as C++ exceptions but it covers more than the usual error cases standard C++ code normally handles.
Descriptors (TDesc, TBuf and HBuf all belong to the descriptor class hierarchy) and templates (arrays, queues, lists...) predate their equivalent in standard C++ while dealing with issues like the CleanupStack, coding standards, memory management and integrity...
A relevant plug if you want to learn about it: Quick Recipes On Symbian OS is a recent attempt at explaning it all in as few pages as possible.
You should also definitely look at the Foundation website to get started.
Classes prefixed by T are meant to be small enough by themselves that they can be allocated on the stack.
Descriptor classes suffixed by C are meant to be immutable (A mutable descriptor can usually be created from them, though).
HBufC is pretty much the only Symbian class prefixed by H. It should always be allocated on the Heap.
A method suffixed by C will add an object on the CleanupStack when it returns successfully (usually, it's the object it returns). It's up to the calling code to Pop that object.
Classes prefixed by R are meant to be allocated on the stack but manage their own heap-based resources. They usually have some kind of Close() method that needs to be called before their destructor.
A typical way to thing about the differences between a collection of objects and a collection of pointers to object is who owns the objects in the collection. Either the collection owns the objects when they are added and looses them when they are removed (and is therefore responsible for deleting each object it still contains when it is itself destroyed) or the collection doesn't transfer ownership and something else must ensure the objects it contains will stay valid during the collection's lifetime.
Another way to think about collections is about how much copying of objects you want to happen when you add/get objects to/from the collection.
Symbian descriptor and collection classes are meant to cover all these different ways of using memory and let you choose the one you need based on what you want to do.
It's certainly not easy to do it right but that's how this operating system works.
This might be a dumb question to some of you and maybe I asked this question wrong, because I am new to C++. But I notice when working in a lot of Win32 applications, you use a lot of resources that are pointers. Why do you have to always acquire a objects pointer? Why not initiate a new instance of the class. and speaking of that, I notice in most cases you never initiate new objects, but always call on methods that return that pointer. What if that pointer is being used somewhere else. Couldn't you mess something up if you alter that pointer and it is being used somewhere else?
Windows APIs were designed for C, which was and still is the most used language for system programming; C APIs are the de-facto standard for system APIs, and for this almost all other languages had and have some way to call external C functions, so writing a C API helps to be compatible with other languages.
C APIs need just a simple ABI, that consists of almost just the definition for the calling convention to use for functions (and something about the structures layout). C++ and other object oriented languages, on the contrary, require a complex ABI, that must define how objects are laid out in memory, how to handle inheritance, how to lay out the vtable, how to propagate exceptions, where to put RTTI data, ... Moreover not all the languages are object oriented, and using APIs thought for C++ with other non-object oriented languages may be a real pain (if you ever used COM from C you know what I mean).
As an aside, when Windows was initially designed C++ wasn't so widespread on PCs, and also C wasn't used so much: actually, a large part of Windows 3.11 and many applications were still written in assembly, since the memory and CPU constraints at the era were very tight; compilers were also less smart than now are, especially C++ ones. On machines where hand-forged assembly was often the only solution, the C++ overhead was really unacceptable.
For the pointers thing: Windows APIs use almost always handles, i.e. opaque pointers, to be able to change the underlying nature of every resource without affecting the existing applications and to stop applications to mess around with internal structures. It doesn't matter if the structure used by the window manager to represent a window internally is changed: all the applications use simply an HWND, which is always of the size of a pointer. You may think at this as some kind of PIMPL idiom.
However, Windows is in some way object-oriented (see for example the whole "window class" concept, or, at a deeper level, the inner working of the NT kernel, which is heavily based on the "object" concept), however its most basic APIs, being simple C functions, somehow hide this OO nature. The shell, on the other side, being designed many years after, is written mostly in C++ and it provides a really object-oriented COM interface.
Interestingly, you can see in COM all the tradeoffs that you must face in building a cross-language but still C++ biased object-oriented interface: the result is quite complicated, in some respects ugly and not really simple to use from any language. The Windows APIs, instead, being simple functions are generally more easily callable.
If you are interested in a system based on C++ APIs you may have a look at Haiku; personally, this is one of the aspects because of which I am quite interested in that project.
By the way, if you are going to do Win32 programming just with the APIs you'd better get a good book to get used to these "particularities" and to other Win32 idioms. Two well-known ones are the Rector-Newcomer and the Petzhold.
Because Win32 Api are written on plain C, not C++. So any program on almost any language can make call to those API.
Plus, there are not simple mechanism to use objects across diferent modules, and diferent languages. I.e. you can't export C++ class to python. Of course, there are technoligies like OLE/COM, but they still written on plain C. And they are bit comlicated to use.
At other hand - calls to plain C functions are standardized. So you can call routines from DLL or static lib in any language.
Win32 was designed to work with the C language not C++.
That's why you will see return types of the defined BOOL instead of bool for example.
bool is specific to C++ and doesn't exist in C.
For Microsoft's object oriented wrapper of Win32 see MFC.
A newer framework from Microsoft since then is the .Net Framework.
The .Net framework is based on managed code though and does not run natively. The most modern way to do GUI programming on Windows is WPF or even Silverlight.
The most modern way to do unmanaged GUI programming is still using MFC, although some people still prefer using straight Win32.
Note working with pointers is not specific to C, it is still very common in C++.
First reason is because passing pointers around is cheap. Pointers are 4 bytes on x86 and 8 bytes on x64. While the structure or class it points to can occupy a whole lot more in memory. So instantiating a class means reserving new memory again and again. This isn't efficient from speed and memory consumption POVs.
Another way is to pass references to objects or smart pointers or similar constructs. But win32 api was designed in the C era, so this is where it is up to now ;)
As about potential messing up with pointers - it's possible of course. But most of the time their lifetime is explicitly stated in the API (if not obvious).
Probably because the Win32 API is "older" than mainstream object-oriented programming, it's not a C++ API at its core.
Its almost like you should try one of the many OO wrappers. Like MFC or .net.
The Windows API is plain old C, hence the use of pointers everywhere. Also, the reason you ask Windows for a new pointer is because Windows needs to keep track of all objects... it allocates things and tells you a pointer (or sometimes just a numeric ID) to let you work with them.
Having C functions as the API allows both C and C++ programmers use it.
Windows APIs goes way back - C was famous during those days.
All the HWND, HANDLE, HDC are but a weak attempt to make clamped, objects-like data types (using struct). C FAQ has a question on this -> http://c-faq.com/struct/oop.html.
To understand the pointers you might want to read the CPlusPlus.com tutorial on pointers.
I have an application written in Delphi that compiles in Delphi 2007. I think it was originally written in Delphi 7.
Anyway, I need to convert all the core non-GUI code into C++ because I want to release a Mac version of the software.
What is the best way to do this? Any shortcuts I can take to speed up the process?
EDIT: The code compiles to native code, not .NET.
Simple answer: You simply can't port non-trivial Delphi code to C++ without a complete rewrite. C++'s object model is very different from Delphi's. It doesn't have a base class like TObject from which all other objects are derived, and it lacks support for a lot of the RTTI stuff that Delphi code often takes for granted. And there's no simple way to reimplement Delphi RTTI in C++, since a lot of it's done at the compiler level, and a lot of it's based on the fact that all Delphi classes descend from TObject.
C++ also lacks support for the concept of unit initialization and finalization sections that are so common in Delphi, and what it has instead is badly broken. (Look up the "static order initialization fiasco" for all the gory details.)
Delphi's exception handling is also much more advanced than C++'s. Part of this is the object model and part of it's compiler magic. Plus, C++ has no support for the try-finally construct.
If you want to port a Delphi project to the Mac, Free Pascal is your best solution. It's not 100% compatible with Delphi, but it's good enough for a lot of things, and you specifically mentioned that you don't need to port the Delphi GUI stuff. AFAIK the GUI area is the source of most of FPC's compatibility weaknesses, so if that's not necessary, FPC is probably pretty close to ideal for your needs, at least until CodeGear gets an OSX compiler out. (Which hasn't been officially announced, but based on various things that have been said it's not unreasonable to suppose that one will be available sometime next year.)
For converting your code from Delphi to Cpp, have a look at
http://ivan.vecerina.com/code/delphi2cpp/.
I used this to convert some of the classes and functions in SysUtils, DateUtils and StrUtils using wxWidgets functions. If you are planning to use wxWidgets for C++ have a look at http://twinforms.com/products/wxwidgets/wxvcl.php which has all the converted source.
If you want directly develop Mac OSX applications using then have a look at wxForms for Delphi - http://twinforms.com/products/wxformsdelphi/index.php
I think this would be difficult to do mechanically, so you are probably looking at a complete re-write. One thing to bear in mind is that typically Delphi uses try...finally structures for resource management, whereas C++ uses a technique known as RAII (resource acquisition is initialisation). You should read up on this and other C++ idioms before you attempt the conversion.
If your code compiles in Delphi 2007 into .NET assemblies, you may have a much easier option than trying to port from Delphi's object pascal to C++.
You could potentially compile your logic into .NET assemblies (and maybe even portions of the UI), and use Mono to run it on Mac. You could write a custom GUI around Mono, or even potentially make a single, platform independent application.
You can use also Delphi Prism. It's for .NET, but it's the last expression in Delphi language spec. It supports also Mac OSX (see the link). Also the guys from CodeGear/EMBT are in the works for a new compiler as well as for a new version of Delphi which is expected to enter in beta in April and narrow the gap between Prism and RAD studio. See their 'Beta Programs' page.
The "correct" way to do this is to rewrite it in Objective C. I find Objective C a little weird, but there are a lot of similarities with Delphi in the way objects connect and delegate.
You may be able to use Free Pascal to do it more quickly, but you should seriously consider a rewrite.
I would be in love with Embarcadero if they could release a Mac OS X version of Delphi that didn't, you know, suck like Kylix did. One can dream.
Edit: There is a great benefit to staying in Delphi, and having a separate version for the Mac in Objective C. First, it means you don't need to rewrite the version on Windows, losing the (presumably) years of investment in Delphi code. Second, Mac software operates differently than Windows, from a UI perspective. A simple port of the product is inappropriate, and hobbles the developer from using the great native features of Windows and Mac. See: older versions of MS Word for Mac, or iTunes for Windows. They look and feel wrong.