What are the things that I should keep in mind to write portable code?
Keep several compilers nearby, test code regularly on target platforms. If you're doing cross-platform software for windows windows/linux , keep around mingw, visual studio express (i.e. "microsoft compiler"), and a linux installation with g++ (or use virtual machine). Even if your code is perfect, compiler might have some kind of unexpected quirk. For example, certain versions of ms compiler have a limit on sizes of string constants, which gcc doesn't have.
Do not rely on sizes of standard types. For example, on msvc sizeof(wchar_t) is 2 bytes. On linux installation it can be 4 bytes. Use sizeof (if you need it), or try to avoid having to use size of any type in your code. And you should not assume that pointer is 4 bytes large (passing user data pointer into api call scenario) - it will be 8 bytes on 64 bit.
Do not use compiler-specific pragmas, macros and extensions. For example, avoid "#pragma once".
Do not use extensions to standard library (provided by compiler developer). This more applicable to C library functions, though. For example, MS compiler provides multiple "safe" (like strcpy_s) versions of standard C-style routines. Which, of course, won't be available on other platforms.
Be very careful if you decide to use C-style routines (like sprintf) in C++ code. (I know that it is supposed to be a bad practice, but in some scenarios this is useful) They have slightly different implementations, extensions, and different number of parameters. For example, sprintf may have different additional formats that are implemented differently on different platforms. For example, last time I checked "%S" behaves differently on msvc and gcc in vswprintf routine.
Do not rely on compiler-specific data types, like __int32. It is very likely that you'll need some kind of type that is guaranteed to be 4 bytes long (or something like that) - use typedef combined with conditional compilation ("#ifdef WIN32"). OR use types provided by cross-platform library. For example, SDL provides types like Uint8, Qt 4 has quint32, etc. This is pretty common practice.
Avoid direct OS calls. Use standard functions for accessing files.
When you have to use OS-specific calls, use conditional compilation (#ifdef WIN32, etc)
Try to use same build system on all platforms. There is no MSBuild on linux. Use gnumake, cmake, scons or qmake. While in some of those systems you will have to code in flags for different compiler, it will be possible to use same script everywhere. FOr example, it works nicely with SConstructs. And maintaining one building script for all platforms may be easier than synchronizing changes across different build systems.
For all operations that require interaction with operating system (Gui, file manipulation), use cross-platform libraries. Qt is a good choice.