I am working on tracing the constructor and its destructed instance and for that I am planning to log the value of "this" in constructor and destructor. I don't know whether it is safe to log value of "this" in constructor. If it is not safe then I wan't to know the scenarios where it will fail ?
If by "logging" you mean "writing out the value as e.g. a hexadecimal address to a log file", it is fine and safe. If not, please clarify.
Objects are not fully constructed until the constructor call is finished. So before that (i.e. from within the constructor) it is not safe to publish this to the rest of the program. Because that might result in someone trying to actually use the half-constructed object. This may lead to subtle and hard to find bugs.
Publishing this may mean one of the following things:
passing it as a parameter to an external (non-member) function,
storing it in a data structure available to other objects,
(for the sake of completeness: returning it from a function call - which does not apply in this specific case, because you can't return anything from a constructor).
Writing out the address of this to a file is thus not publishing it to the rest of your program* so it should be fine.
*well, unless you do some very arcane things afterwards, like loading back the address from the file in a different thread/process and casting it back to an object pointer... which is already unsafe enough by itself :-)
Memory is allocated first, then this is set, then the constructor(s) is called. So you're fine to use this during the constructor, as it points to the right place - the construction won't change this. However if construction fails (throws) the memory will disappear and the value pointed to by this will be garbage so you shouldn't store it and use it for anything outside the constructor until you know the construction will succeed.
Why would you think it is not safe? it is no different to logging the address of any objects in fact so long as those objects are valid.
The long and short of it is that it is safe in the scenarios you are intending to use it for.
Related
I have noticed that, in our codebase, there are some classes that are only used to hold data in their members. In order to clean the members, we call each class' clear() command. However, I've also noticed that, clean methods call other cleans and, which in cascade, results in calling clear() of std data types like string and vectors. Therefore, there seems to be a huge amount of redundant code written.
To minimize the amount of work in the reduction process I am planning to turn each clear method to the following. What are other details I may be missing and your suggestions?
void aClass::clear() {
this->~aClass();
*this = aClass();
}
Thank you
You are missing that your call to the destructor is wrong here. You could simply assign:
*this = aClass();
However, then
This is not what a clear method is supposed to do. You are creating a new object not clearing it. If you clear a string then no reallocations need to happen. Deleting a string and creating a new one is really more work, not less.
As a corrollary to the first point, clear does not take parameters, while your constructor probably does. Again, default constructing a new instance is not what is expected from clear and sometimes it isn't even possible (when there is no default constructor).
Moreover, lets say you do implement clear like this. Then the method adds nothing that the user of the class could not do with a call to a constructor. Instead x.clear(); they could write x = aClass();.
Summary: If you have lots of code to clear objects in your code base, then this is very likely for a reason. Clearing an instance can usually be done with much less computational effort than creating a new instance. On the other hand if this is not the case, then there is no point in implementing a clear method (provided that there is an accessible constructor to create a new instance).
What are other details I may be missing
The destructor still clears the standard containers that are destroyed. Not only that, but it also re-creates them at a cost.
References to the cleared object will become invalid. This can easily lead to undefined behaviour unless you are careful.
and your suggestions?
Write a normal function that doesn't involve the destruction of the object.
Nooooooooooooooooooooo.
Don't do that.
The destructor isn't just a function that calls some operations on your members.
It ends the lifetime of your object.
Period. Full stop.
You cannot call the destructor then keep using the object. Invoking its assignment operator with a temporary doesn't bring it back to life, either; that just, well, invokes the assignment operator to change some values. Values that no longer exist.
There are a few cases where invoking the destructor is reasonable, but they all involve "very manual memory management" using placement new. There are basically no other acceptable times to do it.
Review the notion of object lifetime in C++.
If your copy assignment operator is correctly written, then just *this = aClass(); is already fine for resetting your objects. You might also consider aClass().swap(*this), with the appropriate move-capable swap being added to your class.
These are not "redundant" operations.
I have "inherited" a design where we are using a few global objects for doing stuff when the application exits (updating application status log files, etc ... not important to the question).
Basically the application creates dummy helper objects of specific classes and lets their destructor do these extra works when the application exits either normally or when an error was encountered (and the application knows what to do in all the cases, again not relevant to the question).
But now I have encountered a situation where I do not want to call these destructors, just leave the application without executing these "termination jobs". How can I do this in a decent, platform independent way? I do not want a solution such as divide with zero :)
Edit: I know the design is broken :) We are working on fixing it.
Edit2: I would like to avoid any "trace" of abnormal exit... Sorry for late specification.
Edit3: Obtaining access to the source code for the destructors in order to modify them is very difficult. This happens when politicians take over the keyboard and try to write programs. We just know, that "their" destructor will run on exit...
How can I do this in a decent, platform independent way?
You can't. At least not in a decent way.
You can accomplish this by throwing an exception and not catching it. The end result will be that your application will terminate quite ungracefully. Destructors will not be called. This is quite ugly, very hackish. If your design relies on this behavior to function correctly, well not only is your design completely demented, but it will be near-impossible to maintain.
I would prefer setting a boolean flag in the objects you don't want to run the destructors for. If this flag is set, then the destruction code would not be run. The destructors will still fire, but the actual code you want to avoid running can be skipped.
If you control the construction of the global, you might be able to leverage operator placement-new. Construct a global char buffer big enough for your global, then placement-new your global there. Since objects constructed this way must be destroyed by explicitly calling the destructor, simply don't call the destructor on shutdown for the global.
abort();
Aborts the current process, producing an abnormal program termination.
The function raises the SIGABRT signal (as if raise(SIGABRT) was
called). This, if uncaught, causes the program to terminate returning
a platform-dependent unsuccessful termination error code to the host
environment.
The program is terminated without destroying any object and without
calling any of the functions passed to atexit or at_quick_exit.
Taking your comment of "we know it's broken"...
Put a global bool somewhere
bool isExiting;
Set this to true when exiting.
In your destructors do
if( !global::isExiting )
{
// destruction code here
}
Hide somewhere, and be thoroughly ashamed.
The easiest is to replace the global objects by heap-allocated pointers to the objects. That way, in order to run their destructors, you have to manually delete them. Be aware that this is of course very, very nasty. A better way than using a raw pointer is to use a std::unique_ptr and, in case the destructor shouldn’t be called, release it.
If you don’t want to change the client code which is interacting with the global objects (and expect a non-pointer type), just wrap the actual pointer into a global proxy object.
(PS: There are few but very legitimate reasons for such a design. Sometimes it’s entirely safe not to call destructors, and calling them may be detrimental, e.g. because it’s known that they only release memory, but will take very long due to many nested destructor calls. This still needs to be done very carefully but is not at all “bad design”.)
It is ugly but it works:
Create simple maker class.
Maker's constructorr should allocate the object of your liking and assign it to a static pointer.
Make sure that nothing is done in maker's destructor.
Create single static instance of maker object.
To make things look better, make the static pointer private andwrite inline accessor function that will convert the static pointer you have to a public reference.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How much work should be done in a constructor?
I'm strugging with some advice I have in the back of my mind but for which I can't remember the reasoning.
I seem to remember at some point reading some advice (can't remember the source) that C++ constructors should not do real work. Rather, they should initialize variables only. The advice went on to explain that real work should be done in some sort of init() method, to be called separately after the instance was created.
The situation is I have a class that represents a hardware device. It makes logical sense to me for the constructor to call the routines that query the device in order to build up the instance variables that describe the device. In other words, once new instantiates the object, the developer receives an object which is ready to be used, no separate call to object->init() required.
Is there a good reason why constructors shouldn't do real work? Obviously it could slow allocation time, but that wouldn't be any different if calling a separate method immediately after allocation.
Just trying to figure out what gotchas I not currently considering that might have lead to such advice.
I remember that Scott Meyers in More Effective C++ recommends against having a superfluous default constructor. In that article, he also touched on using methods liked Init() to 'create' the objects. Basically, you have introduced an extra step which places the responsibility on the client of the class. Also, if you want to create an array of said objects, each of them would have to manually call Init(). You can have an Init function which the constructor can call inside for keeping the code tidy, or for the object to call if you implement a Reset(), but from experiences it is better to delete an object and recreate it rather than try to reset its values to default, unless the objects is created and destroyed many times real-time (say, particle effects).
Also, note that constructors can perform initialization lists which normal functions could not.
One reasons why one may caution against using constructors to do heavy allocation of resources is because it can be hard to catch exceptions in constructors. However, there are ways around it. Otherwise, I think constructors are meant to do what they are supposed to do - prepare an object for its initial state of execution (important for object creation is resource allocation).
The one reason not to do "work" in the constructor is that if an exception is thrown from there, the class destructor won't get called. But if you use RAII principles and don't rely on your destructor to do clean up work, then I feel it's better not to introduce a method which isn't required.
Depends on what you mean by real work. The constructor should put the object into a usable state, even if that state is a flag meaning it hasn't yet been initialised :-)
The only rationale I've ever come across for not doing real work would be the fact that the only way a constructor can fail is with an exception (and the destructor won't be called in that case). There is no opportunity to return a nice error code.
The question you have to ask yourself is:
Is the object usable without calling the init method?
If the answer to that is "No", I would be doing all that work in the constructor. Otherwise you'll have to catch the situation when a user has instantiated but not yet initialised and return some sort of error.
Of course, if you can re-initialise the device, you should provide some sort of init method but, in that case, I would still call that method from the constructor if the condition above is met.
In addition to the other suggestions regarding exception handling, one thing to consider when connecting to a hardware device is how your class will handle the situation where a device is not present or communication fails.
In the situation where you can't communicate with the device, you may need to provide some methods on your class to perform later initialization anyway. In that case, it may make more sense to just instantiate the object and then run through an initialization call. If the initialization fails, you can just keep the object around and try to initialize communication again at a later time. Or you may need to handle the situation where communication is lost after initialization. In either case, you will probably want to think about how you will design the class to handle communication problems in general and that may help you decide what you want to do in the constructor versus an initialization method.
When I've implemented classes that communicate with external hardware, I've found it easier to instantiate a "disconnected" object and provide methods for connecting and setting up initial status. This has generally provide more flexibility connecting/disconnecting/reconnecting with the device.
The only real reason is Testability. If your constructors are full of "real work", that usually means the objects can only be instantiated within a fully initialized, running application. It's a sign the object/class needs further decomposition.
When using a constructor and an Init() method you have a source of error. In my experience you will encounter situation where someone forgets to call it, and you might have a subtle bug in your hands. I would say you shouldn't do much work in your constructor but if any init method is needed, then you have a non-trivial construction scenario, and it is about time to look at the creational patterns. A builder function or a factory be wise to have a look at. With a private constructor making sure that no one except your factory or builder function actually build the objects, so you can be sure that it is always constructed correctly.
If your design allow for mistakes in implementation, someone will do those mistakes. My friend Murphy told me that ;)
In my field we work with loads of similar hardware related situations. Factories gives us both testability, security and better ways of failing construction.
It is worth considering lifetime issues and connecting/reconnecting, as Neal S. points out.
If you fail to connect to a device at the other end of a link then it is often the case that the 'device' at your end is usable and will be later if the other end gets its act together. Examples being network connections etc.
On the other hand if you try and access some local hardware device that does not exist and will never exist within the scope of your program (for example a graphics card that is not present) then I think this is a case where you want to know this in the constructor, so that the constructor can throw and the object can not exist. If you don't then you may end up with an object that is invalid and will always be so. Throwing in the constructor means that the object will not exist, and thus functions can't be called on that object. Obviously you need to be aware of cleanup issues if you throw in a constructor, but if you don't in cases like this then you typically end up with validation checks in all functions that may be called.
So I think that you should do enough in the constructor to ensure you have a valid, usable, object created.
I'd like to add my own experience there.
I won't say much about the traditional debate Constructor/Init... for example Google guidelines advise against anything the in the Constructor but that's because they advise against Exceptions and the 2 work together.
I can speak about a Connection class I use though.
When the Connection class is created, it will attempt to actually connect itself (at least, if not default constructed). If the Connection fails... the object is still constructed and you don't know about it.
When you try to use the Connection class you are thus in one of 3 cases:
no parameter has ever been precised > exception or error code
the object is actually connected > fine
the object is not connected, it will attempt to connect > this succeeds, fine, this fails, you get an exception or an error code
I think it's quite useful to have both. However, it means that in every single method actually using the connection, you need to test whether or not it works.
It's worth it though because of disconnection events. When you are connected, you may lose the connection without the object knowing about it. By encapsulating the connection self-check into a reconnect method that is called internally by all methods needing a working connection, you really isolate the developers from dealing with the issues... or at least as much as you can since when everything fails you have no other solution that letting them know :)
Doing "real work" in a constructor is best avoided.
If I setup database connections, open files etc inside a constructor and if in doing so one of them raise an exception then it would lead to a memory leak. This will compromise your application's exception safety.
Another reason to avoid doing work in a constructor is that it would make your application less testable. Suppose you are writing a credit-card payment processor. If say in CreditCardProcessor class's constructor you do all the work of connecting to a payment gateway, authentate and bill the credit card how do I ever write unit tests for CreditCardProcessor class?
Coming to your scenario, if the routines that query the device do not raise any exceptions and you are not going to test the class in isolation then there is its probably preferable to do work in the constructor and avoid calls to that extra init method.
There are a couple reasons I would use separate constructor/init():
Lazy/Delayed initialization. This allows you to create the object quickly, fast user response, and delay a more lengthy initialization for later or background processing. This is also a part of one or more design patterns concerning reusable object pools to avoid expensive allocation.
Not sure if this has a proper name, but perhaps when the object is created, the initialization information is unavailable or not understood by whoever is creating the object (for example, bulk generic object creation). Another section of code has the know-how to initialize it, but not create it.
As a personal reason, the destructor should be able to undo everything the constructor did. If that involves using internal init/deinit(), no problem, so long as they are mirror images of each other.
I have an object which implements reference counting mechanism. If the number of references to it becomes zero, the object is deleted.
I found that my object is never deleted, even when I am done with it. This is leading to memory overuse. All I have is the number of references to the object and I want to know the places which reference it so that I can write appropriate cleanup code.
Is there some way to accomplish this without having to grep in the source files? (That would be very cumbersome.)
A huge part of getting reference counting (refcounting) done correctly in C++ is to use Resource Allocation Is Initialization so it's much harder to accidentally leak references. However, this doesn't solve everything with refcounts.
That said, you can implement a debug feature in your refcounting which tracks what is holding references. You can then analyze this information when necessary, and remove it from release builds. (Use a configuration macro similar in purpose to how DEBUG macros are used.)
Exactly how you should implement it is going to depend on all your requirements, but there are two main ways to do this (with a brief overview of differences):
store the information on the referenced object itself
accessible from your debugger
easier to implement
output to a special trace file every time a reference is acquired or released
still available after the program exits (even abnormally)
possible to use while the program is running, without running in your debugger
can be used even in special release builds and sent back to you for analysis
The basic problem, of knowing what is referencing a given object, is hard to solve in general, and will require some work. Compare: can you tell me every person and business that knows your postal address or phone number?
One known weakness of reference counting is that it does not work when there are cyclic references, i.e. (in the simplest case) when one object has a reference to another object which in turn has a reference to the former object. This sounds like a non-issue, but in data structures such as binary trees with back-references to parent nodes, there you are.
If you don't explicitly provide for a list of "reverse" references in the referenced (un-freed) object, I don't see a way to figure out who is referencing it.
In the following suggestions, I assume that you don't want to modify your source, or if so, just a little.
You could of course walk the whole heap / freestore and search for the memory address of your un-freed object, but if its address turns up, it's not guaranteed to actually be a memory address reference; it could just as well be any random floating point number, of anything else. However, if the found value lies inside a block a memory that your application allocated for an object, chances improve a little that it's indeed a pointer to another object.
One possible improvement over this approach would be to modify the memory allocator you use -- e.g. your global operator new -- so that it keeps a list of all allocated memory blocks and their sizes. (In a complete implementation of this, operator delete would have remove the list entry for the freed block of memory.) Now, at the end of your program, you have a clue where to search for the un-freed object's memory address, since you have a list of memory blocks that your program actually used.
The above suggestions don't sound very reliable to me, to be honest; but maybe defining a custom global operator new and operator delete that does some logging / tracing goes in the right direction to solve your problem.
I am assuming you have some class with say addRef() and release() member functions, and you call these when you need to increase and decrease the reference count on each instance, and that the instances that cause problems are on the heap and referred to with raw pointers. The simplest fix may be to replace all pointers to the controlled object with boost::shared_ptr. This is surprisingly easy to do and should enable you to dispense with your own reference counting - you can just make those functions I mentioned do nothing. The main change required in your code is in the signatures of functions that pass or return your pointers. Other places to change are in initializer lists (if you initialize pointers to null) and if()-statements (if you compare pointers with null). The compiler will find all such places after you change the declarations of the pointers.
If you do not want to use the shared_ptr - maybe you want to keep the reference count intrinsic to the class - you can craft your own simple smart pointer just to deal with your class. Then use it to control the lifetime of your class objects. So for example, instead of pointer assignment being done with raw pointers and you "manually" calling addRef(), you just do an assignment of your smart pointer class which includes the addRef() automatically.
I don't think it's possible to do something without code change. With code change you can for example remember the pointers of the objects which increase reference count, and then see what pointer is left and examine it in the debugger. If possible - store more verbose information, such as object name.
I have created one for my needs. You can compare your code with this one and see what's missing. It's not perfect but it should work in most of the cases.
http://sites.google.com/site/grayasm/autopointer
when I use it I do:
util::autopointer<A> aptr=new A();
I never do it like this:
A* ptr = new A();
util::autopointer<A> aptr = ptr;
and later to start fulling around with ptr; That's not allowed.
Further I am using only aptr to refer to this object.
If I am wrong I have now the chance to get corrections. :) See ya!
Can C++ objects be copied using bitwise copy? I mean using memcopy_s? Is there a scenario in which that can go wrong?
If they're Plain Old Data (POD) types, then this should work. Any class that has instances of other classes inside it will potentially fail, since you're copying them without invoking their copy constructors. The most likely way it will fail is one of their destructors will free some memory, but you've duplicated pointers that point to it, so you then try to use it from one of your copied objects and get a segfault. In short, don't do it unless it's a POD and you're sure it will always be a POD.
No, doing so can cause a lot of problems. You should always copy C++ types by using the assignment operator or copy constructor.
Using a bitwise copy breaks any kind of resource management because at the end of the day you are left with 2 objects for which 1 constructor has run and 2 destructors will run.
Consider as an example a ref counted pointer.
void foo() {
RefPointer<int> p1(new int());
RefPointer<int> p2;
memcpy(&p2,p1,sizeof(RefPointer<int>));
}
Now both p1 and p2 are holding onto the same data yet the internal ref counting mechanism has not been notified. Both destructors will run thinking they are the sole owner of the data potentially causing the value to be destructed twice.
It depends on the implementation of the C++ object you are trying to copy. In general the owner of the C++ object's memory is the object itself, so trying to "move" or "copy" it with something like memcopy_s is going behind its back which is going to get you in trouble more often than not.
Usually if a C++ object is intended to be copied or moved, there are APIs within the class itself that facilitate this.
If it is a single object, why not use assignment operator (I suppose the compiler-generated assignment operator could be implemented in terms of memcpy if that is so advantageous, and the compiler knows better whether your class is a POD.)
If you want to copy an array of objects, you can use std::copy. Depending on the implementation, this may end up using memmove (one more thing that you can mess up - the buffers may overlap; I don't know whether the nonstandard memcpy_s somehow checks for that) if the involved types allow that. Again, the decision is done by the compiler, which will get it right even if the types are modified.
In general if your structure contains pointers, you can't memcpy it because the structure would most likely allocate new memory spaces and point to those. A memcpy can't handle that.
If however your class only has primitive, non-pointer types, you should be able to.
In addition to the problem of unbalanced resource management calls in the two instance you end up with after a memcopy (as #JaredPar and #rmeador pointed), if the object supports a notion of an instance ID doing a memcopy will leave you with two instances with the same ID. This can lead to all sorts of "interesting" problems to hunt later on, especially if your objects are mapped to a database.