#ifdef 64BIT
.. something 64 bit specific
#else
.. something 32 bit specific
#endif
I achieved this goal but had to resolve the following problem.
Problem 1 : Code did not compile
#include<algorithm>
using namespace std;
unsigned int w;
.....
max(w,sizeof(..));
Another solution could be to create custom MAX template:
template < class T1, class T2 >
T1 MAX( T1 x, T2 y ) {
if ( x < y ) return y;
return x;
}
Problem 2: Hard test that unsigned long is 4 bytes long.
config.h
...
#define SIZEOF_LONG 4
if (sizeof(usigned long) != SIZEOF_LONG) {
throw error ....
}
#ifdef BIT64
#define SIZEOF_LONG 8
#else
#define SIZEOF_LONG 4
#endif
Problem 3: 32/64 file locking.
I needed simple mutex mechanism to allow only one process to do some administering task (like indexing common resources first time after installing). There are many synchronization methods available but to keep it as simple as possible I utilized lock mechanism on files.
Code snippet:
bool mutexOp(const std::string &semname,bool lock) {
// use simple hash function for mapping string to number
unsigned long no = 0l;
for (int i=0; semname[i]; i++) no = (17*no) + (semname[i]-32);
int lockfd;
// get lockfd of file being used as semaphore
struct flock fs;
fs.l_type = lock ? F_WRLCK : F_UNLCK;
fs.l_whence = SEEK_SET;
fs.l_start = no;
fs.l_len = 1; // lock one byte only
int res = fcntl( lockfd, F_SETLK, & fs );
// ...........
// analize res
}
The solution is very simply, just do it yourself.
unsigned long no = 0l;
for (int i=0; semname[i]; i++) no = (17*no) + (semname[i]-32);
no &= 0xffffffff;
Problem 4: Last but not least.
Application uses embedded indexed-sequential (ISAM) data base. One of the data types supported is 'unsigned long' keeping numbers 4 bytes long. 64 bit version should also support this 4 bytes unsigned longs to handle data bases created by 32 bit version. It was the problem I feared the most, it looked for me like an endless chain of fixing, patching, refactoring ... But there is also good news that solution was very simple.
Application was originally designed that data base field types (int, long, double) could be differ than its counterpart in C++ program. So there is a common point of conversion between stream of bytes read from data base to C++ data types and vice versa and fix was very simple.
void convertStreamOfBytes(int fType, const void *sou, void *dest, bool todb)
{
switch (fType) {
case ...
case ulongfield:
#ifdef BIT64
if (todb) {
*reinterpret_cast (dest) = *reinterpret_cast (sou);
} else {
*reinterpret_cast (dest) = *reinterpret_cast (sou);
}
#else
*reinterpret_cast (dest) = *reinterpret_cast (sou);
#endif
break;
case ...
}
}
Conclusion
So finally the goal was achieved. Application is 64 enabled, backward compatibility is kept and only few branchings inside the code.
But it is hard to say what real advantage it gives. The binaries are 10-15% greater. I don't think that it runs faster. Of course, I can address 64-bit space but this application is not memory thirsty. The only real advantage seems that it can be installed and run in pure 64 environment without necessity to install any 32 bit system components (e.g. 32 bit Python).
Welcome 64 bit world.