C语言中U64、uint64_t与long的区别及各自优势
Hey there! Let's break down the differences between U64, uint64_t, and long for you—especially since you're working on that chess magic bitboard code, which is such a neat use of low-level integer operations!
1. U64 – The Project-Specific Alias
First off, U64 isn’t a standard C type—it’s a custom type alias (defined via typedef somewhere in the codebase you’re replicating). In chess bitboard projects like this, it almost always maps to either unsigned long long or uint64_t—both 64-bit unsigned integers.
Its big advantage is readability and brevity: typing U64 is quicker than unsigned long long, and it makes it immediately clear the variable is meant for 64-bit bitboard work. The only downside? It’s project-specific—if you move this code to another project, you’ll need to ensure the same typedef exists, or replace it with a standard type.
2. uint64_t – The Standardized 64-bit Workhorse
uint64_t is a standard C type from the <stdint.h> header (part of the C99 standard). It’s guaranteed to be an unsigned 64-bit integer on any platform that supports C99 or later—no exceptions.
Its greatest strength is portability. Whether you’re compiling on a 32-bit Raspberry Pi, 64-bit Linux, or Windows, uint64_t will always be 64 bits. This is critical for code that relies on fixed-size integers (like your magic bitboard code, where every bit corresponds to a chess square). If you want your code to work reliably across systems without surprises, uint64_t is the way to go.
3. long – The Platform-Dependent Wildcard
long is a classic C type, but its size isn’t fixed. Here’s the catch:
- On 32-bit systems,
longis almost always 32 bits. - On 64-bit Linux/macOS,
longis 64 bits. - On 64-bit Windows,
longis still 32 bits (they uselong longfor 64 bits).
This variability makes long a terrible choice for your bitboard code. If you assume long is 64 bits, your code will break on 32-bit systems or 64-bit Windows—bitmask operations, shifts, and table lookups will all behave incorrectly. The only "advantage" is historical familiarity, which isn’t a good reason to use it for fixed-size needs.
Quick Advantage Breakdown
| Type | Key Advantages | Best For |
|---|---|---|
U64 | Short, readable, project-consistent syntax | In-project code where brevity matters |
uint64_t | 100% portable, standard, fixed 64-bit size | Cross-platform code, long-term maintainability |
long | Historical familiarity | Legacy code only—avoid for fixed-size needs |
Applying This to Your Chess Code
The magic bitboard code relies entirely on 64-bit unsigned integers to track board state and calculate attacks. If you want to replace U64 with uint64_t (for better portability), just add this at the top of your code:
#include <stdint.h> typedef uint64_t U64;
This keeps the concise U64 syntax while tying it to the standard, portable uint64_t type. Your code will work exactly the same, but you won’t have to worry about platform-specific size issues.
内容的提问来源于stack exchange,提问作者Finn Eggers

