Glad I could help :)
not_in_use
Posts
-
try-catch dynamic memory cleanup -
Inlining QuestionAs far as I understand it they won't be inlined, just like regular constants. I have pretty much the same problem right now, except that I don't need to switch types. In this thread I posted my current idea for a workaround (using operator overloading and inline functions), maybe that could help you. It's a hack, but in theory it should work. As for your templating idea, if you don't need both float and double versions at the same time, you could just use typedefs like so:
// .h file
typedef double myFpType; // Changing this to float changes the type of all constantsconst myFpType pi;
...// .cpp file
const myFpType pi = myFpType( 3.14159265358979 );
...or using my workaround idea from the link above:
typedef double myFpType;
// In .h file
INLINE_CONST( myFpType, pi, myFpType( 3.14159265358979 ) );But maybe someone knows a better solution that could help us both out. Hope that helps, Peter
-
Quick Newbie question about naming conventionsIt's not specific to C++. Different projects use different naming conventions, so depending on whose code you look at it will vary greatly. It's really a matter of preference. The C++ standard library comes all in one single namespace called
std
that deals with basic stuff like string manipulation, lists etc., whereas the .NET API pretty much wraps the entire OS API. The C++ library can get away with much shorter names since its feature set is very limited and defined, whereas .NET needs means to organize all that stuff, and it does so by using tons of nested namespaces, which results in much longer symbol names overall. I agree that most STL class names are not necessarily immediatly comprehensible and are thus not really a good example to follow in terms of naming conventions. Nor are the MFC, which were conceived before design patterns, templates, and namespaces had reached the real world, plus they are massively influenced by the Windows API naming conventions and are overall much closer to a C library than to a modern C++ library. My advice is to be as verbose as you need to be but as short as you can be without sacrificing clarity. The time you save when you use cryptic abbreviations is far less than the time it is going to cost when someone has to fix a bug in that code, or even just understand what it does. If you want an example of what readable C++ code with good coding conventions and modern design looks like, check out the open source FreeCloth project. Reading through that code really changed the way I had been thinking about a few things. Hope this helps, Peter -
try-catch dynamic memory cleanupObjects allocated on the heap (i.e. via
new
) are not freed automatically. Objects allocated on the stack (likeMyObject obj;
) are freed when they go out of scope (i.e. when the execution leaves the innermost {} that surrounds the declaration) or when an exception is thrown. So in your example, iffailfunc()
throws an exception other than an integer (which can easily happen when someone changes failfunc() but not main()), you got yourself a memory leak. However, you can use what's called a smart pointer to get the desired behavior. The smart pointer is is a helper class that is allocated on the stack and behaves like a regular pointer, and when an exception is thrown its destructor gets called. In that destructor, it calls delete[] on its pointee. Just google smart pointers. Example (not tested)://
// Smart pointer class for arrays
//
template< typename T >
class ArrayPtr
{public:
ArrayPtr( T\* pointee ) : \_pointee( pointee ) { } inline ~ArrayPtr() { if( \_pointee ) delete\[\] \_pointee; // Array destruction } operator T\*() { return \_pointee } // ... more needed here. Just google smart pointers. // Basically you need operator->, operator\*, but not operator& // plus assignment etc.
private:
T\* \_pointee;
};
//
// How to use it in your example
//
void failfunc()
{
throw 1; // obviously not practical, just for example
}void main()
{
try {
ArrayPtr< char > mystr( new char[512] ); // Freed automatically when mystr goes out of scope or an exception is thrown
failfunc();
} catch( int err ) {
// Tell the user something went wrong
std::cerr << "Error #" << err << std::endl;
}
}Or if you don't need to print out an error message:
template< typename T > class ArrayPtr { /*... see above*/ };
void failfunc() { /*... see above*/ }
void main()
{
ArrayPtr< char > mystr( new char[512] ); // Freed automatically when mystr goes out of scope or an exception is thrown
failfunc();
}Note that you cannot use the standard C++ std::auto_ptr for arrays since its destructor only calls
delete
, notdelete[]
. This also implies that you need a separate smart pointer type for data allocated withmalloc
since it must be freed usingfree
, notdelete[]
-
Inlining of constsThanks for your reply. Inline functions are not a problem with DLLs since the implementation has to be inside the header files, which means that the source code is available and can be inlined by the compiler, so no problem there. The solution you are proposing is exactly what the macro from my post would do (the macro would just add the benefit that it is transparent to client code because it would provide the semantics of a regular const). But I found it hard to believe that C++ offers no built-in solution. I mean, the standard allows inlining of functions, but it doesn't seem to be able to inline constants. Well, I guess I'll just have to bite the bullet and live with it then. Thanks again, Peter
-
Inlining of constsHi everyone, I have a question that may sound a bit strange: What's the most efficient and elegant way to define constants in C++? I'm in a situation where I have to define constants that might be used in code that needs to be as fast as possible (such as maybe image or sound processing for example). I know the standard way in C++ is like this:
// myFile.h
const float myConst;// myFile.cpp
const float myConst = 3.5;Based on my understanding, the initialization must be performed in
myFile.cpp
since only int constants can be initialized in the header. The problem is that this looks a lot like the constant won't be inlined but always read from memory (or processor cache of course) when it is accessed. What's worse is that client code will most likely usemyFile
as part of a DLL/SO, so even if there were the slightest chance that the linker were trained to perform some magic inlining when linking the binary, I'd still be out of luck. Apart from that I need a portable solution that works reliably on Windows, Linux, Mac OS X, and if possible also on SGI Irix, independent of the compiler and linker. The obvious solution is to just use#define myConst 3.5
, but I'd like to avoid that if possible (for obvious reasons). If I'm right about no inlining being performed, does anyone have any proven workaround for this? All I could come up with was maybe abusing inline functions roughly like so (not tested, just an idea):#define INLINE_CONST( TYPE, NAME, VALUE ) \
struct FastConst_T_##NAME { \
inline operator TYPE { return (VALUE); } \
} NAMEwhich then could be used like that:
INLINE_CONST( double, pi, 3.141592653589793238462 ); // Pi from my memory, don't copy without checking
inline double circleArea( radius ) {
return r * r * pi;
}But that's obviously not a very elegant solution. I'm really sorry for the lengthy post, but I can't believe I have to use such hacks to get C++ to inline my constant values. I already tried Google, but I didn't find anything useful. Thanks in advance, Peter