I'm a bit surprised by this. unsigned long is typically 32
bits; on 64-bit systems size_t tends to be 64 bit. A cast
would _not_ work!
The current C++ standard guarantees that unsigned long be the
largest integral type available, as did C90. If an
implementation makes size_t 64 bits, but unsigned long 32, it's
not C++ (but it will be C++ when the next version of the
standard appears). In practice, most implementations for 64 bit
systems make long 64 bits, as this is the only reasonable choice
for such systems. (Arguably, int should also be 64 bits on such
systems, but there are various reasons why this is not usually
the case.)
Note that in C90 and C++, the guarantee that long was the
largest integral type was an important one---more important in
C90, of course. And there was very extensive discussion in the
C committee about allowing larger types, with a great deal of
opposition precisely because it broke things like
``printf("%ul",(unsigned long)a_size_t)'' (which had been
guaranteed), and broke them in the worst way. On the other
hand, it was realized that there would probably be a need in the
future for even larger types (uint256_t, etc.), and even on 32
bit machines, there was a need for a 64 bit integral type, so
the committee bit the bullet. Still, from a quality of
implementation point of view, I wouldn't expect an
implementation to make size_t larger than unsigned long unless
there were two or more types larger than int.