5 ms·
#3 is bad (or at least incomplete) advice when you consider portability to 64-bit. What it should say is to use the C type that correctly represents the data.
by jmgao 12y ago
#3 is bad (or at least incomplete) advice when you consider portability to 64-bit. What it should say is to use the C type that correctly represents the data.
Translating DWORD to `unsigned long` is not correct! unsigned long is 32 bits on x86_64 Linux, but 64 bits on x86_64 Windows. Using long is essentially never correct for cross-platform code.
The right thing to do depends on what the value represents. If you want a 32 bit unsigned integer, use uint32_t. If you want something representing a pointer or size, use the corresponding type (uintptr_t, size_t). This doesn't just make porting easier, it adds useful hints for anyone reading your code.
- sharpneli 12y agoIt's actually vice versa. long is 64bit on amd64 linux and 32bit on amd64 windows.
- foxhill 12y agoreally, the issue is, if you want a fixed bitwidth data type, use the types in unistd.h - uint64_t or uint32_t.
- omilu 12y agobut fixed width data types are super freaking slow if your doing intensive processing.
- foxhill 12y agoum.. what do you mean, exactly? all types in C are fixed bitwidth. but the uintx_t types make it obvious what what programmer wants.
- brianwski 12y agoI'm not buying it. I want to see your timings and proof. First of all, this only applies to a very few internal loops that don't touch disk, so you can use the "cross platform rule" for 99.999 percent of code. But if you are down to that last inner loop that runs your 3D video game, I'll admit you will need to have platform dependent code paths. But this describes an infinitesimally tiny subset of the code in the world. The rest of the time, write easy to understand cross platform less buggy code!
- mikeash 12y agoThe last part of that entry makes me wonder if the guy even understands what's going on: "The most important place to apply this rule is in cross platform library code. You can't even call into a function that takes a DWORD argument on a Macintosh, so the argument should be passed in as an unsigned long." If DWORD is declared, then your Mac code can use it fine. If it's not, then it won't even compile. At no point can you ever reach a point where "you can't even call into a function that takes a DWORD argument".
- brianwski 12y agoAuthor here (late to the discussion, nobody told me my 2008 article was posted on hackernews...) > If DWORD is declared, then your Mac code can use it fine. > If it's not, then it won't even compile. Correct -> as a WINDOWS programmer you think it's fine because it compiles just fine. The point is it then won't compile on the Mac, or on Linux, or any other platform. The whole point is if you want a 32 bit integer, use a cross platform 32 bit integer from the beginning. When a Macintosh programmer goes to compile, it will compile. ONLY IF you need to call a Windows specific call, then type cast or convert into the Windows specific type, and then you do it inside an #ifdef. But most all of the time Windows programmers seem to love their DWORDS and they use them all over the place, even for public APIs that some other poor Macintosh programmer has to replace later. Why not start with the cross platform version? What does a DWORD get you that "int32_t" does not? (NOTE: we make sure "int32_t" is defined and a 32 bit integer on all of our platforms, then everybody uses the same thing.)
- brianwski 12y agoHey, brianwski the author here, unfortunately I didn't realize my (2008) web page was on Hacker News until somebody told me. :-) Anyway, in my old age I feel that the "ambiguous size types" in 'C' are outright evil. Size is REALLY important, it's not like you can just declare an "int" and know in your heart it is "big enough", you need to absolutely be sure that the values you put in it will fit. So I like using explicitly sized integers in all situations, why not? The ONLY argument I can fathom for "let the compiler decide on this integer's size" is performance, and frankly if that is your performance problem (and not disk I/O) then you need to be focusing on that problem WAAAAAAY more than just letting the compiler decide how big your integer is.