NEVER use "#define" to declare a constant or a macro, especially in header files! This could be tolerated in cpp files but it's a bad habit anyway!
Prefer either an "static const", an "enum" or a template function instead (or better, a non-template inline function)
BAD example:
#define NO_ERROR 0
#define MIN(A,B) (((A)<(B))?(A):(B))
GOOD example:
static const int NO_ERROR = 0;
template <class T> T min(T a, T b) { (a<b)?a:b; }
This will avoid the side-effect of preprocessor definitions
While not being a developer I would like to lend a tip or two.
Prefer either an "static const", an "enum" or a template function instead (or better, a non-template inline function)
...
GOOD example:
static const int NO_ERROR = 0;
template <class T> T min(T a, T b) { (a<b)?a:b; }
Why not make the template functions inline? They have no disadvantage with respect to non-template functions. (Yes, old compilers ALWAYS bloated the code before, but not anymore nowadays.) Using this kind of templates is both simple and advisable:
namespace my {
inline template<typename T> T min(T a, T b) { return a <= b ? a : b; }
inline template<typename T> T max(T a, T b) { return a >= b ? a : b; }
inline template<typename T> T sqr(T a) { return a*a; }
};
This will avoid the side-effect of preprocessor definitions
Please allow me to complement zieQ's coding style advice by supplying a "textbook example" of how a macro can mess up your code.
Suppose you define a macro that expands your variables to be squared, i.e.:
Now, suppose you use this macro for a certain expression.
A natural way to write it in a given context would be for example:
int n = 5;
...
int m = SQR(n++);
So m should end up being equal to 25 while n finishes as 6, right? Wrong. A macro makes a _textual_ replacement of the expression in the parenthesis by its definition. The compiler replaces what you wrote by
So, in fact, m is equal to 30, and n is equal to 7.
You can easily conclude what might happen with complicated expressions. The consequences of systematically using macros to handle pointers can be much worse, with hard to track segmentation faults.
Needless to say, the above example, with the inline function template shown above, ( my:: sqr() ) would be parsed normally as any function, without any surprises. Type safety is a Good Thing(TM).
Another tip, though maybe not so useful, would be the use of namespaces separation for code clarity. I'd like to see further use of namespaces in the SDK, so I'm posting that as a feature request in sourceforge. Though low priority, I know.
Best regards
Wanted to check codeblocks for memory errors. How to compile codeblocks against mpatrol (there's an .exe installer at mingw sourceforge):
1) have gcc include mpatrol.h with each source file:
-include mpatrol.h
2) specify multiple definitions of malloc(), etc are OK linker option:
-Wl,--allow-multiple-definition
3) make sure mpatrol (mpatrolmt) libraries occur before other libraries (which define malloc(), etc):
-lmpatrolmt -limagehlp -lbfd -liberty --lwxmsw26 -lgdi32
So, goto build options
under compiler->other options add
-include mpatrol.h
under linker->other link options add
-Wl,--allow-multiple-definition
under linker->link libraries add (***before all other libraries***)
mpatrolmt
imagehlp
bfd
iberty
(You also need to set the linker settings for the console runner target)
So that should give something like: -lmpatrolmt -limagehlp -lbfd -liberty -lwxmsw26 -lgdi32
when it links.
That should be it. There's a mpatrol.pdf that installs with the mpatrol installer. Basically just run codeblocks.exe and look for a mpatrol.log afterwards. Compiling right now, will test the results later.
Edit: looks like bfd is the wrong object file format for windows. I'll try recompiling mpatrol and see if it works then
Edit: nevermind, it looks like mpatrol doesn't want to work. I just tried the above flags with a simple win32gui app and then putting int* abc = new int[10]; (so that the mpatrol libs are actually linked in)
it gives:
ERROR: [ILLMEM]: illegal memory read at address 0x00000000
0x00000000 not in heap
call stack
0x00000000 ???
0x0041082C ???
0x0040218C ???
0x00402BF3 ???
0x0041A70F ???
0x0047176D ???
0x004715B7 ???
0x00471399 ???
0x004011E7 ???
0x00401238 ???
0x7C816D4F RegisterWaitForInputIdle+73
No matter if I delete the memory properly or not. Looks like mpatrol just isn't working right with winxp or something. Any other suggestions for memory checking with mingw?
Edit: OK, I finally figured out mpatrol. Uninstall the mpatrol .exe installer. The precompiled version on the mingw site is "broken":
"I suspect that the gcc C++ ABI has changed since
the downloaded library was built. That would
explain mysterious behavior if true. Try building
the library from source."
http://groups.yahoo.com/group/mpatrol/message/880
Edit: ignore the url below. grab the source at the mingw site which they already patched (better too since it generates dlls).
So download the source:
http://www.cbmamiga.demon.co.uk/mpatrol/
extract to c:\ and then open an MSYS prompt and do:
cd /usr; mkdir local; ln -s "/c/MinGW/include" include; ln -s "/c/MinGW/lib" lib
vi /etc/profile
export LD_LIBRARY_PATH = "/usr/local/lib:$LD_LIBRARY_PATH"
source /etc/profile
place the attached patch in c:\ and change to the extracted mpatrol directory:
cd /c/mpatrol
patch -p1 -i ../mpatrol-1.4.8-mingw.patch.txt
cd build/unix
make clean
make all
copy generated files to the right place
create
c:\MinGW\include\mpatrol
c:\MinGW\doc\mpatrol
cp *.h "/c/MinGW/include/mpatrol"
mv "/c/MinGW/include/mpatrol/{mpatrol.h,mpalloc.h,mpdebug.h}" "/c/MinGW/include"
cp *.lib *.exp *.so "/c/MinGW/lib"
copy the contents of the mpatrol\doc directory to c:\MinGW\doc\mpatrol
All set. To test build a new Win32GUI application.
Add
int* abc = new int[10];
after the case WM_DESTROY:
(compare with later adding delete[] abc; as well. or even just delete abc; which leaks but doesn't crash... but mpatrol catches this)
Next goto build options:
check produce debugging symbols (-g)
compiler->other options =
-include mpatrol.h
linker->link libraries =
mpatrol
imagehlp
bfd
iberty
gdi32
user32
kernel32
other link options is blank since we are linking the static libmpatrol.a (dynamic .so one requires -Wl,--allow-multiple-definition)
rebuild and then open a cmd prompt
set MPATROL_OPTIONS=PROF LEAKTABLE
(see the documentation...)
and run:
Win32GUI.exe
exit the app and then look at:
mpatrol.log
also try at the cmd prompt:
mprof
you should see...
top 2 unfreed memory entries in leak table:
bytes count location
-------- ------ --------
60 1 ___w32_sharedptr_initialize
40 1 main.cpp line 85
100 2 total
cool, huh? Shows you exactly where you put a new[] and then later never delete[]ed.
[attachment deleted by admin]