1e41f4b71Sopenharmony_ci# 32- and 64-Bit Portability Coding Guide
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## About This Document
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci### Purpose
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciOpenHarmony aims to build an open, distributed OS framework for smart IoT devices in the full-scenario, full-connectivity, and full-intelligence era. It has the following technical features: hardware collaboration for resource sharing, one-time development for multi-device deployment, and a unified OS for flexible deployment.
8e41f4b71Sopenharmony_ciOpenHarmony supports the following system types:
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci1. Mini system: a device oriented to devices that have MCU processors such as ARM Cortex-M and 32-bit RISC-V. These devices have limited hardware resources. The minimum device memory is 128 KiB.
11e41f4b71Sopenharmony_ci2. Small system: a device oriented to devices that have application processors such as 64-bit ARM Cortex-A. The minimum device memory is 1 MiB.
12e41f4b71Sopenharmony_ci3. Standard system: a device oriented to devices that have application processors such as 64-bit ARM Cortex-A. The minimum device memory is 128 MiB.
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ciOpenHarmony code can run on 32- and 64-bit devices. For easier code portability, clear coding specifications are necessary. This document stipulates the specifications on code porting and 64-bit coding, helping you improve code standardization and portability.
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci### Application Scope
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ciC and C++ code for the user space and kernel space, without distinguishing the programming language standards.
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci### Differences Between 32-Bit OS and 64-Bit OS
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci#### Data Type Differences
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ciMost 32-bit OSs use ILP32, which defines int, long, and pointer as 32 bits. Most 64-bit OSs use LP64, which defines long, long long, and pointer as 64 bits. The Windows OS uses LLP64, which defines long long and pointer as 64 bits. The table below lists the length of each primitive data type.
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci| **Type**| **ILP32** | **LP64** | **LLP64** | **LP32** | **ILP64** |
27e41f4b71Sopenharmony_ci| --------- | --------- | -------- | --------- | -------- | --------- |
28e41f4b71Sopenharmony_ci| char      | 1         | 1        | 1         | 1        | 1         |
29e41f4b71Sopenharmony_ci| short     | 2         | 2        | 2         | 2        | 2         |
30e41f4b71Sopenharmony_ci| int       | 4         | 4        | 4         | 2        | 8         |
31e41f4b71Sopenharmony_ci| long      | **4**     | **8**    | **4**     | 4        | 8         |
32e41f4b71Sopenharmony_ci| long long | 8         | 8        | 8         | 8        | 8         |
33e41f4b71Sopenharmony_ci| float     | 4         | 4        | 4         | 4        | 4         |
34e41f4b71Sopenharmony_ci| double    | 8         | 8        | 8         | 8        | 8         |
35e41f4b71Sopenharmony_ci| size_t    | **4**     | **8**    | **8**     | 4        | 8         |
36e41f4b71Sopenharmony_ci| pointer   | **4**     | **8**    | **8**     | 4        | 8         |
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ciThe table below lists the length of `sizeof` and `print` in ILP32 and LP64 to show the differences between constants and types.
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ci| Type               | ILP32 sizeof | ILP32 print | LP64 sizeof | LP64 print | Remarks|
41e41f4b71Sopenharmony_ci| ------------------ | ------------ | ----------- | ----------- | ---------- | ------ |
42e41f4b71Sopenharmony_ci| bool               | 1            | %u          | 1           | %u         | C++    |
43e41f4b71Sopenharmony_ci| char               | 1            | %d or %c| 1           | %d or %c|        |
44e41f4b71Sopenharmony_ci| unsigned char      | 1            | %u          | 1           | %u         |        |
45e41f4b71Sopenharmony_ci| short              | 2            | %d          | 2           | %d         |        |
46e41f4b71Sopenharmony_ci| unsigned short     | 2            | %u          | 2           | %u         |        |
47e41f4b71Sopenharmony_ci| int                | 4            | %d          | 4           | %d         |        |
48e41f4b71Sopenharmony_ci| unsigned int       | 4            | %u          | 4           | %u         |        |
49e41f4b71Sopenharmony_ci| long               | 4            | %ld         | **8**       | %ld        | Differences exist.|
50e41f4b71Sopenharmony_ci| unsigned long      | 4            | %lu         | **8**       | %lu        | Differences exist.|
51e41f4b71Sopenharmony_ci| long int           | 4            | %ld         | **8**       | %ld        | Differences exist.|
52e41f4b71Sopenharmony_ci| unsigned long int  | 4            | %lu         | **8**       | %lu        | Differences exist.|
53e41f4b71Sopenharmony_ci| long long          | 8            | %lld        | 8           | %lld       |        |
54e41f4b71Sopenharmony_ci| unsigned long long | 8            | %llu        | 8           | %llu       |        |
55e41f4b71Sopenharmony_ci| type \*             | 4            | %p          | **8**       | %p         | Differences exist.|
56e41f4b71Sopenharmony_ci| pid_t              | 4            | %d          | 4           | %d         |        |
57e41f4b71Sopenharmony_ci| socklen_t          | 4            | %u          | 4           | %u         |        |
58e41f4b71Sopenharmony_ci| off_t              | 4            | %zd         | **8**       | %zd        | Differences exist.|
59e41f4b71Sopenharmony_ci| time_t             | 4            | %zd         | 8           | %zd        | Differences exist.|
60e41f4b71Sopenharmony_ci| pthread_t          | 4            | %zu         | **8**       | %zu        | Differences exist.|
61e41f4b71Sopenharmony_ci| size_t             | 4            | %zu         | 8           | %zu        | Differences exist.|
62e41f4b71Sopenharmony_ci| ssize_t            | 4            | %zd         | **8**       | %zd        | Differences exist.|
63e41f4b71Sopenharmony_ci
64e41f4b71Sopenharmony_ci#### Differences in Data Structure Alignment
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_ci##### Alignment of the data structure that contains a pointer
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ci```c
69e41f4b71Sopenharmony_citypedef struct tagFoo {
70e41f4b71Sopenharmony_ci    void *p;
71e41f4b71Sopenharmony_ci    uint32_t i;
72e41f4b71Sopenharmony_ci} Foo;
73e41f4b71Sopenharmony_ci```
74e41f4b71Sopenharmony_ci
75e41f4b71Sopenharmony_ciOn a 32-bit OS, the pointer length is 4, **Foo** is 4-byte aligned, and **sizeof(Foo)** is 8. On a 64-bit OS, the pointer length is 8, **Foo** is 8-byte aligned, and **sizeof(Foo)** is 16.
76e41f4b71Sopenharmony_ci
77e41f4b71Sopenharmony_ci##### Alignment of the data structure that contains a 64-bit integer
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci```c
80e41f4b71Sopenharmony_citypedef struct tagFoo {
81e41f4b71Sopenharmony_ci    uint64_t p;
82e41f4b71Sopenharmony_ci    uint32_t i;
83e41f4b71Sopenharmony_ci} Foo;
84e41f4b71Sopenharmony_ci```
85e41f4b71Sopenharmony_ci
86e41f4b71Sopenharmony_ciAlthough uint64\_t has a fixed length, **sizeof(Foo)** is different due to alignment. On a 32-bit OS, **Foo** is 4-byte aligned, and **sizeof(Foo)** is 12. On a 64-bit OS, **Foo** is 8-byte aligned, and **sizeof(Foo)** is 16. The preceding statement is also true when uint64\_t is replaced by double.	
87e41f4b71Sopenharmony_ci
88e41f4b71Sopenharmony_ci### Conventions
89e41f4b71Sopenharmony_ci
90e41f4b71Sopenharmony_ci**Rule**: Conventions that must be complied with during programming.
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci**Rec**: Conventions that should be complied with during programming.
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci## Coding Guide
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_ci### General Principles
97e41f4b71Sopenharmony_ci
98e41f4b71Sopenharmony_ci#### [Rule] Follow this coding guide to write code that is applicable to both 32- and 64-bit OSs.
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci[Description] OpenHarmony will run in both 32- and 64-bit environments for a long time. To ensure code consistency, you must consider code portability during coding.
101e41f4b71Sopenharmony_ci
102e41f4b71Sopenharmony_ci### Data Type Definition and Formatting
103e41f4b71Sopenharmony_ci
104e41f4b71Sopenharmony_ci#### [Rule] Use the defined data types to define variables, and avoid custom basic data types without special meanings or requirements.
105e41f4b71Sopenharmony_ci
106e41f4b71Sopenharmony_ci[Description] Data types with variable lengths may cause incompatibility issues on 32- and 64-bit OSs. Unified and clear data types are required. OpenHarmony defines the following primitive data types:
107e41f4b71Sopenharmony_ci
108e41f4b71Sopenharmony_ci| Type| ILP32 | LP64  | Print| Use Case|
109e41f4b71Sopenharmony_ci| ---------------- | ----- | ----- | ------- | ------------------------------------------------------------ |
110e41f4b71Sopenharmony_ci| void             | -     | -     | -       | Used only for placeholder and general pointer definition.|
111e41f4b71Sopenharmony_ci| char             | 1     | 1     | %c      | Used for strings and arrays.|
112e41f4b71Sopenharmony_ci| int8_t           | 1     | 1     | %d      | Used for 1-byte integers.|
113e41f4b71Sopenharmony_ci| uint8_t          | 1     | 1     | %u      | Used for 1-byte integers.|
114e41f4b71Sopenharmony_ci| int16_t          | 2     | 2     | %d      | Used to replace short.|
115e41f4b71Sopenharmony_ci| uint16_t         | 2     | 2     | %u      | Used to replace unsigned short.|
116e41f4b71Sopenharmony_ci| int32_t          | 4     | 4     | %d      | Used to replace int.|
117e41f4b71Sopenharmony_ci| uint32_t         | 4     | 4     | %u      | Used to replace unsigned int.|
118e41f4b71Sopenharmony_ci| int64_t          | 8     | 8     | %PRId64 | Used to replace long long and macros.|
119e41f4b71Sopenharmony_ci| uint64_t         | 8     | 8     | %PRIu64 | Used to replace unsigned long long and macros.|
120e41f4b71Sopenharmony_ci| float            | 4     | 4     | %f      | Used for single-precision floating point numbers.|
121e41f4b71Sopenharmony_ci| double           | 8     | 8     | %lf     | Used for double-precision floating point numbers.|
122e41f4b71Sopenharmony_ci| bool             | 1     | 1     | %d      | Used for Boolean.|
123e41f4b71Sopenharmony_ci| uintptr_t        | **4** | **8** | %zu     | Used for pointer storage. Different lengths are defined for 32- and 64-bit OSs.|
124e41f4b71Sopenharmony_ci| type \*           | **4** | **8** | %p      | Variable-length type. It is equivalent to uintptr_t, which is recommended for type conversion.|
125e41f4b71Sopenharmony_ci| nullptr_t        | **4** | **8** | %p      | Used for pointer initialization.|
126e41f4b71Sopenharmony_ci| pid_t            | 4     | 4     | %d      | Built-in for the Linux kernel. It has a fixed length.|
127e41f4b71Sopenharmony_ci| socklen_t        | 4     | 4     | %u      | Built-in for the Linux kernel. It has a fixed length.|
128e41f4b71Sopenharmony_ci| off_t/time_t     | **4** | **8** | %zd     | Signed, variable-length type.|
129e41f4b71Sopenharmony_ci| size_t/pthread_t | **4** | **8** | %zu     | Unsigned, variable-length type. It is used only for compatibility of calling library functions (for example, size_t is used in an underlying API).|
130e41f4b71Sopenharmony_ci
131e41f4b71Sopenharmony_ciThe preceding types are defined in the **stddef.h** (C) and **cstdint** (C++) standard libraries. When `#define` is used to redefine related types, the source must be one of these types.
132e41f4b71Sopenharmony_ci
133e41f4b71Sopenharmony_ciDo not use non-standard types unless otherwise specified. Do not define common basic types unless they have special meanings. For primitive data types used in third-party interfaces and API calling, refer to their respective rules.
134e41f4b71Sopenharmony_ci
135e41f4b71Sopenharmony_ci[Example] Do not customize primitive data types unless necessary.
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ci```c
138e41f4b71Sopenharmony_ci// Do not use the following code to redefine a data type.
139e41f4b71Sopenharmony_citypedef unsigned int UINT32;// This definition is forbidden.
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ci// The preceding definition can be replaced by uint32_t. However, you can define a type that has a specific meaning.
142e41f4b71Sopenharmony_citypedef uint32_t DB_TABLE_ID; // This definition can be retained.
143e41f4b71Sopenharmony_ci```
144e41f4b71Sopenharmony_ci
145e41f4b71Sopenharmony_ci[Example] Do not use the following two types, because their lengths are different from the common sense.
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ci| Type| ILP32  | LP64  | PRINT | Use Case|
148e41f4b71Sopenharmony_ci| -------- | ------ | ----- | ----- | ---------------------- |
149e41f4b71Sopenharmony_ci| float_t  | **12** | **4** | -     | Improper length. Do not use it.|
150e41f4b71Sopenharmony_ci| double_t | **12** | **8** | -     | Improper length. Do not use it.|
151e41f4b71Sopenharmony_ci
152e41f4b71Sopenharmony_ci#### [Rec] Do not use custom variable-length variables. A clear description is required if they are used to adapt to platforms or third-party interfaces.
153e41f4b71Sopenharmony_ci
154e41f4b71Sopenharmony_ci[Description] The native types such as long, int, short, and size_t have different lengths in the 32- and 64-bit environments. This may cause code risks. If these types are used for external storage or communication, system incompatibility may occur. Therefore, do not use them unless otherwise specified.
155e41f4b71Sopenharmony_ci
156e41f4b71Sopenharmony_ci[Exception] Due to platform, third-party interface, or library function reasons, they can be used with a clear description.
157e41f4b71Sopenharmony_ci
158e41f4b71Sopenharmony_ci[Example]
159e41f4b71Sopenharmony_ci
160e41f4b71Sopenharmony_ci```c
161e41f4b71Sopenharmony_cilong var;
162e41f4b71Sopenharmony_ci// This data type is 4-byte long on a 32-bit OS and 8-byte long on a 64-bit OS. You are advised to use uint32_t or uint64_t instead.
163e41f4b71Sopenharmony_ci```
164e41f4b71Sopenharmony_ci
165e41f4b71Sopenharmony_ci#### [Rule] Do not use uchar to define variables.
166e41f4b71Sopenharmony_ci
167e41f4b71Sopenharmony_ci[Description] It is not standard to use uchar or unsigned char to define strings. Instead, use char for strings or uint8_t for unsigned integers.
168e41f4b71Sopenharmony_ci
169e41f4b71Sopenharmony_ciFor non-ANSI character sequences involving 8-bit encoding, char is recommended. In C++, wchar can be used.
170e41f4b71Sopenharmony_ci
171e41f4b71Sopenharmony_ci#### [Rule] Define an integer variable that is used to store a pointer as uintptr_t.
172e41f4b71Sopenharmony_ci
173e41f4b71Sopenharmony_ci[Description] The uintptr_t type is used to store data of the pointer length. The length can be automatically adjusted in the 32- and 64-bits environments.
174e41f4b71Sopenharmony_ci
175e41f4b71Sopenharmony_ci[Example]
176e41f4b71Sopenharmony_ci
177e41f4b71Sopenharmony_ci```c
178e41f4b71Sopenharmony_ciuintptr_t sessionPtr;
179e41f4b71Sopenharmony_ci
180e41f4b71Sopenharmony_ci// When the pointer is stored as a variable, both the forced type conversion and left value should be defined as uintptr_t to adapt to the length changes in different scenarios.
181e41f4b71Sopenharmony_cisessionPtr = (uintptr_t) GetMemAddress();
182e41f4b71Sopenharmony_ci```
183e41f4b71Sopenharmony_ci
184e41f4b71Sopenharmony_ci#### [Rec] When the type defined by the input parameter or return value of a function does not match the variable type, exercise caution to ensure that the result is correct after conversion following the value assignment and type conversion rules.
185e41f4b71Sopenharmony_ci
186e41f4b71Sopenharmony_ci[Description] If type inconsistency is inevitable, convert the type with caution to ensure that the final result meets the application requirements.
187e41f4b71Sopenharmony_ci
188e41f4b71Sopenharmony_ci[Example]
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ci```c
191e41f4b71Sopenharmony_cilong function (long l);
192e41f4b71Sopenharmony_ciint main () {
193e41f4b71Sopenharmony_ci    int i = -2;
194e41f4b71Sopenharmony_ci    unsigned int k = 1U;
195e41f4b71Sopenharmony_ci    long n = function(i + k);
196e41f4b71Sopenharmony_ci}
197e41f4b71Sopenharmony_ci```
198e41f4b71Sopenharmony_ci
199e41f4b71Sopenharmony_ciNote: The preceding code will fail to be executed on a 64-bit OS because the expression (i + k) is an unsigned 32-bit expression. When it is converted to the long type, the symbols are not extended. The result of the input parameter is incorrect. The solution is to forcibly convert one of the operands to a 64-bit type.
200e41f4b71Sopenharmony_ci
201e41f4b71Sopenharmony_ci#### [Rule] Use 64-bit compatible macros, such as %PRId64, %PRIu64, and %PRIx64, to print 64-bit integers. Incompatible macros, such as %d, %ld, %zd, %x, and %lx, are not allowed.
202e41f4b71Sopenharmony_ci
203e41f4b71Sopenharmony_ci[Description] If the data to be formatted is of the 64-bit type (defined as uint64_t), format the output as follows:
204e41f4b71Sopenharmony_ci
205e41f4b71Sopenharmony_ci```c
206e41f4b71Sopenharmony_ci#include <stdio.h>
207e41f4b71Sopenharmony_ci#include <stdint.h>
208e41f4b71Sopenharmony_ci#include <inttypes.h>
209e41f4b71Sopenharmony_ci
210e41f4b71Sopenharmony_ciint main()
211e41f4b71Sopenharmony_ci{
212e41f4b71Sopenharmony_ci    uint64_t a = 0x1234567fffffff;
213e41f4b71Sopenharmony_ci    printf("a = %"PRIx64"\n", a);
214e41f4b71Sopenharmony_ci    return 0;
215e41f4b71Sopenharmony_ci}
216e41f4b71Sopenharmony_ci```
217e41f4b71Sopenharmony_ci
218e41f4b71Sopenharmony_ciThe preceding code can output 64-bit numbers in both 32- and 64-bit environments. If other formatting methods are used, compatibility issues may occur, as listed in the following table.
219e41f4b71Sopenharmony_ci
220e41f4b71Sopenharmony_ci| Formatting Method| ILP32 Build| ILP32 Result| LP64 Build| LP64 Result| Conclusion|
221e41f4b71Sopenharmony_ci| ---------- | -------------- | --------- | -------------- | -------- | ---------- |
222e41f4b71Sopenharmony_ci| %lx        | Type mismatch alarm| Incorrect| No alarm| Correct| Incompatible|
223e41f4b71Sopenharmony_ci| %zx        | Type mismatch alarm| Incorrect| No alarm| Correct| Incompatible|
224e41f4b71Sopenharmony_ci| %llx       | No alarm| Correct| Type mismatch alarm| Correct| Incompatible|
225e41f4b71Sopenharmony_ci| %p         | Type mismatch alarm| Incorrect| Type mismatch alarm| Correct| Incompatible|
226e41f4b71Sopenharmony_ci| %PRIx64    | No alarm| Correct| No alarm| Correct| Compatible|
227e41f4b71Sopenharmony_ci
228e41f4b71Sopenharmony_ci[Example]The following is an example of the type mismatch alarm information:
229e41f4b71Sopenharmony_ci
230e41f4b71Sopenharmony_ci```bash
231e41f4b71Sopenharmony_ci# Build on a 32-bit OS
232e41f4b71Sopenharmony_ciformat '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'uint64_t {aka long long unsigned int}'
233e41f4b71Sopenharmony_ciformat '%zx' expects argument of type 'size_t', but argument 2 has type 'uint64_t {aka long long unsigned int}'
234e41f4b71Sopenharmony_ciformat '%p' expects argument of type 'void *', but argument 2 has type 'uint64_t {aka long long unsigned int}'
235e41f4b71Sopenharmony_ci
236e41f4b71Sopenharmony_ci# Build on a 64-bit OS
237e41f4b71Sopenharmony_ciformat '%llx' expects argument of type 'long long unsigned int', but argument 2 has type 'uint64_t {aka long unsigned int}'
238e41f4b71Sopenharmony_ciformat '%p' expects argument of type 'void *', but argument 2 has type 'uint64_t {aka long unsigned int}'
239e41f4b71Sopenharmony_ci```
240e41f4b71Sopenharmony_ci
241e41f4b71Sopenharmony_ci#### [Rule] When printing type-variable data, consider the data length and reserve sufficient space during alignment.
242e41f4b71Sopenharmony_ci
243e41f4b71Sopenharmony_ci[Description] On a 32-bit OS, the maximum length of the pointer and size_t is 8 bits (hexadecimal) or 10 bits (decimal). On a 64-bit OS, their maximum length is 20 bits. Therefore, you need to consider the length range when printing the data.
244e41f4b71Sopenharmony_ci
245e41f4b71Sopenharmony_ci#### [Rule] Do not use L/UL as the suffix of constants. You can add the suffix U to indicate the unsigned int type and the suffix LL/ULL to indicate the 64-bit length.
246e41f4b71Sopenharmony_ci
247e41f4b71Sopenharmony_ci[Description] By default, constants without suffixes are of the int type. When L/UL is used as the suffix, the length may change on 32- and 64-bit OSs. Therefore, use LL/ULL as the suffix to ensure that the length is fixed at 64 bits in both the 32- and 64-bit environments.
248e41f4b71Sopenharmony_ci
249e41f4b71Sopenharmony_ci| Constant| ILP32     | LP64  | Scenario|
250e41f4b71Sopenharmony_ci| -------------- | --------- | ----- | ------------------------------------------------------------ |
251e41f4b71Sopenharmony_ci| 1              | 4         | 4     | The default type is int32_t, and the length is fixed.|
252e41f4b71Sopenharmony_ci| 1U             | 4         | 4     | The default type is uint32_t, and the length is fixed.|
253e41f4b71Sopenharmony_ci| 1L             | **4**     | **8** | The suffix is L. The length is not fixed. Do not use this constant.|
254e41f4b71Sopenharmony_ci| 1UL            | **4**     | **8** | The suffix is UL. The length is not fixed. Do not use this constant.|
255e41f4b71Sopenharmony_ci| 1LL            | 8         | 8     | The default type is int64_t. The value is a long integer, and the length is fixed at 64 bits.|
256e41f4b71Sopenharmony_ci| 1ULL           | 8         | 8     | The type is uint64_t, and the value is an unsigned long integer.|
257e41f4b71Sopenharmony_ci| 0x7FFFFFFF     | 4         | 4     | The value is an unsigned number. It can be used within the value range of int32\_t. The default type is int32\_t. |
258e41f4b71Sopenharmony_ci| 0x7FFFFFFFL    | **4**     | **8** | The length is not fixed. Do not use this constant.|
259e41f4b71Sopenharmony_ci| 0x7FFFFFFFLL   | 8         | 8     | The length is fixed.|
260e41f4b71Sopenharmony_ci| 0x80000000     | 4         | 4     | It can be used within the value range of uint32\_t. The type is uint32\_t.|
261e41f4b71Sopenharmony_ci| 0x80000000L    | **4**     | **8** | The suffix is L. It can be used within the value range of uint32\_t. This constant is meaningless. Do not use it.|
262e41f4b71Sopenharmony_ci| 0x80000000LL   | 8         | 8     | The suffix is LL. It can be used within the value range of uint32\_t. The length is fixed.|
263e41f4b71Sopenharmony_ci| 0x8000000000   | **NA or 8**| **8** | No prefix. It can be used when the value range of uint32\_t is exceeded. The compiler uses LL by default or considers the value invalid. On a 64-bit OS, the type is fixed at uint64\_t.|
264e41f4b71Sopenharmony_ci| 0x8000000000L  | **NA or 8**| **8** | The suffix is L. It can be used when the value range of uint32_t is exceeded. This constant is meaningless. Do not use it.|
265e41f4b71Sopenharmony_ci| 0x8000000000LL | 8         | 8     | The suffix is LL. The type is uint64_t.|
266e41f4b71Sopenharmony_ci
267e41f4b71Sopenharmony_ciAs shown in the preceding table, a constant with the L or UL suffix has different lengths in the 32- and 64-bit environments. This hinders code portability. Therefore, do not use the L or UL suffix.
268e41f4b71Sopenharmony_ci
269e41f4b71Sopenharmony_ci[Example]
270e41f4b71Sopenharmony_ci
271e41f4b71Sopenharmony_ci```c
272e41f4b71Sopenharmony_ci// UL in the following definition is meaningless. It causes an error on a 32-bit OS and is unnecessary on a 64-bit OS.
273e41f4b71Sopenharmony_ci#define YYY_START_ADDRESS(XXX_START_ADDR + 0x80000000UL)
274e41f4b71Sopenharmony_ci```
275e41f4b71Sopenharmony_ci
276e41f4b71Sopenharmony_ci#### [Rule] Use macro constants defined in the standard header file.
277e41f4b71Sopenharmony_ci
278e41f4b71Sopenharmony_ci[Description] The standard header files **stdint.h** (C) and **cstdint.h** (C++) contain macro constants with the maximum and minimum values. Reference these macro constants, rather than customizing new ones.
279e41f4b71Sopenharmony_ci
280e41f4b71Sopenharmony_ci[Example]
281e41f4b71Sopenharmony_ci
282e41f4b71Sopenharmony_ci```c
283e41f4b71Sopenharmony_ci#include <cstdio>
284e41f4b71Sopenharmony_ci#include <cinttypes>
285e41f4b71Sopenharmony_ci 
286e41f4b71Sopenharmony_ciint main()
287e41f4b71Sopenharmony_ci{
288e41f4b71Sopenharmony_ci    std::printf("%zu\n", sizeof(std::int64_t));
289e41f4b71Sopenharmony_ci    std::printf("%s\n", PRId64);
290e41f4b71Sopenharmony_ci    std::printf("%+" PRId64 "\n", INT64_MIN);
291e41f4b71Sopenharmony_ci    std::printf("%+" PRId64 "\n", INT64_MAX);
292e41f4b71Sopenharmony_ci
293e41f4b71Sopenharmony_ci    std::int64_t n = 7;
294e41f4b71Sopenharmony_ci    std::printf("%+" PRId64 "\n", n);
295e41f4b71Sopenharmony_ci}
296e41f4b71Sopenharmony_ci```
297e41f4b71Sopenharmony_ci
298e41f4b71Sopenharmony_ci#### [Rule] Use unified definitions instead of all Fs to indicate invalid values of constants.
299e41f4b71Sopenharmony_ci
300e41f4b71Sopenharmony_ci[Description] The same numeric constant value may be understood differently on 32- and 64-bit OSs, since the 32-bit OS has the signed and unsigned types. Especially, if the most significant bit is 1, this bit is considered as a negative number on a 32-bit OS based on the signed type and a positive number on a 64-bit OS. Use the definitions in **typedef.h** to indicate invalid values.
301e41f4b71Sopenharmony_ci
302e41f4b71Sopenharmony_ci```c
303e41f4b71Sopenharmony_ci// Use the definitions in typedef.h.
304e41f4b71Sopenharmony_ci#define INVALID_INT8((int8_t)(-1))
305e41f4b71Sopenharmony_ci#define INVALID_UINT8((uint8_t)(-1))
306e41f4b71Sopenharmony_ci#define INVALID_INT16((int16_t)(-1))
307e41f4b71Sopenharmony_ci#define INVALID_UINT16((uint16_t)(-1))
308e41f4b71Sopenharmony_ci#define INVALID_INT32((int32_t)(-1))
309e41f4b71Sopenharmony_ci#define INVALID_UINT32((uint32_t)(-1))
310e41f4b71Sopenharmony_ci#define INVALID_INT64((int64_t)(-1))
311e41f4b71Sopenharmony_ci#define INVALID_UINT64((uint64_t)(-1))
312e41f4b71Sopenharmony_ci```
313e41f4b71Sopenharmony_ci
314e41f4b71Sopenharmony_ci[Example]
315e41f4b71Sopenharmony_ci
316e41f4b71Sopenharmony_ci```c
317e41f4b71Sopenharmony_ci// On a 32-bit OS, n is a negative number.
318e41f4b71Sopenharmony_cilong n = 0xFFFFFFFF;
319e41f4b71Sopenharmony_ci// On a 64-bit OS, n is a positive number. The actual value is 0x00000000FFFFFFFF.
320e41f4b71Sopenharmony_cilong n = 0xFFFFFFFF;
321e41f4b71Sopenharmony_ci```
322e41f4b71Sopenharmony_ci
323e41f4b71Sopenharmony_ci#### [Rec] Use uint32_t to define temporary variables whose size does not exceed 32 bits.
324e41f4b71Sopenharmony_ci
325e41f4b71Sopenharmony_ci[Description] You do not need to pay special attention to the type of a variable. Use the default uint32_t type to minimize forced type conversions caused by type inconsistency.
326e41f4b71Sopenharmony_ci
327e41f4b71Sopenharmony_ci### Structure Alignment and Padding
328e41f4b71Sopenharmony_ci
329e41f4b71Sopenharmony_ci#### [Rule] Do not hardcode a constant to specify the variable length and structure length. Use built-in types such as **sizeof** to obtain the variable length and structure length.
330e41f4b71Sopenharmony_ci
331e41f4b71Sopenharmony_ci[Description] **sizeof** automatically calculates the variable length and structure length, which might be incorrect if hardcoded. In addition, the running performance will not be adversely affected since the variable length is calculated during build.
332e41f4b71Sopenharmony_ci
333e41f4b71Sopenharmony_ciOn a 64-bit OS, 8-byte alignment is used by default. Using **sizeof()** to obtain the structure length can avoid length calculation errors caused by structure alignment.
334e41f4b71Sopenharmony_ci
335e41f4b71Sopenharmony_ciPay attention to the length differences on 32- and 64-bit OSs to avoid length calculation errors. Calculate and apply for space based on the maximum length.
336e41f4b71Sopenharmony_ci
337e41f4b71Sopenharmony_ci[Example] **sizeof** is not used to calculate the structure length, causing insufficient memory space.
338e41f4b71Sopenharmony_ci
339e41f4b71Sopenharmony_ci```c
340e41f4b71Sopenharmony_ciint32_t *p;
341e41f4b71Sopenharmony_cip = (int32_t *)malloc(4 * ELEMENTS_NUMBER);
342e41f4b71Sopenharmony_ci// This code assumes that the pointer length is 4 bytes. However, in LP64, the pointer length is 8 bytes.
343e41f4b71Sopenharmony_ci
344e41f4b71Sopenharmony_ci// The correct method is to use sizeof().
345e41f4b71Sopenharmony_ciint32_t *p;
346e41f4b71Sopenharmony_cip = (int32_t *)malloc(sizeof(p) * ELEMENTS_NUMBER);
347e41f4b71Sopenharmony_ci```
348e41f4b71Sopenharmony_ci
349e41f4b71Sopenharmony_ci#### [Rec] In special cases, force the compiler to use a specific alignment mode on the 64-bit OS.
350e41f4b71Sopenharmony_ci
351e41f4b71Sopenharmony_ci[Description] If necessary, you can use the specified alignment mode to ensure code compatibility. If the pseudo-instruction **#pragma pack (n)** is used, the compiler aligns data by n bytes. If the pseudo-instruction **#pragma pack ()** is used, the compiler cancels the custom byte alignment mode.
352e41f4b71Sopenharmony_ci
353e41f4b71Sopenharmony_ci[Example]
354e41f4b71Sopenharmony_ci
355e41f4b71Sopenharmony_ci```c
356e41f4b71Sopenharmony_ci#pragma pack(push) // Save the current alignment mode.
357e41f4b71Sopenharmony_ci#pragma pack(1) // Set the alignment mode to 1-byte alignment.
358e41f4b71Sopenharmony_cistruct test
359e41f4b71Sopenharmony_ci{
360e41f4b71Sopenharmony_ci    ......
361e41f4b71Sopenharmony_ci};
362e41f4b71Sopenharmony_ci#pragma pack(pop) // Restore the previous alignment mode.
363e41f4b71Sopenharmony_ci```
364e41f4b71Sopenharmony_ci
365e41f4b71Sopenharmony_ci#### [Rule] Uniform the message structures related to multi-device communication. For compatibility purposes, 1-byte alignment is preferred. Do not use 8-byte alignment or 64-bit data types to avoid errors during communication with a 32-bit OS.
366e41f4b71Sopenharmony_ci
367e41f4b71Sopenharmony_ciNote: Inter-board communication messages involve inter-board operations. The communication fails unless all software is upgraded synchronously. For the sake of compatibility, use 1-byte alignment for the existing protocols and structures and convert them into the network byte order. For new communication protocols, use 4-byte alignment for higher communication efficiency and processing performance.
368e41f4b71Sopenharmony_ci
369e41f4b71Sopenharmony_ci#### [Rule] Avoid structure padding for external APIs and use at least 4-byte alignment.
370e41f4b71Sopenharmony_ci
371e41f4b71Sopenharmony_ci[Description] If structure definitions are included in an API header file provided externally, do not pad the structures. It is recommended that natural alignment be used to avoid data holes. Use at least 4-byte alignment.
372e41f4b71Sopenharmony_ci
373e41f4b71Sopenharmony_ci#### [Rec] Use member names to access structure members. Do not use the offset mode.
374e41f4b71Sopenharmony_ci
375e41f4b71Sopenharmony_ci[Description] The offsets of data structure members are different in the 32- and 64-bit environments. Therefore, the size of each member cannot be used as the offset. A 32-bit OS does not have structures automatically padded. However, on a 64-bit OS, automatic padding may occur.
376e41f4b71Sopenharmony_ci
377e41f4b71Sopenharmony_ci[Example]
378e41f4b71Sopenharmony_ci
379e41f4b71Sopenharmony_ci```c
380e41f4b71Sopenharmony_ciStruct A
381e41f4b71Sopenharmony_ci{
382e41f4b71Sopenharmony_ci    uint32_t a;
383e41f4b71Sopenharmony_ci    uint32_t *p;
384e41f4b71Sopenharmony_ci    uint32_t b;
385e41f4b71Sopenharmony_ci};
386e41f4b71Sopenharmony_ci```
387e41f4b71Sopenharmony_ci
388e41f4b71Sopenharmony_ciThe offset of member b is equal to sizeof(a) + sizeof(p) on a 32-bit OS. This is not true on a 64-bit OS. The correct method is to locate the index based on the variable name.
389e41f4b71Sopenharmony_ci
390e41f4b71Sopenharmony_ci```c
391e41f4b71Sopenharmony_cixxx.b = 123;
392e41f4b71Sopenharmony_ci```
393e41f4b71Sopenharmony_ci
394e41f4b71Sopenharmony_ciIf the structure definition is special, for example, if the structure is only the message header and there are other fields, then you can redefine the structure so that it does not include padding fields.
395e41f4b71Sopenharmony_ci
396e41f4b71Sopenharmony_ci[Example]
397e41f4b71Sopenharmony_ci
398e41f4b71Sopenharmony_ci```c
399e41f4b71Sopenharmony_citypedef struct {
400e41f4b71Sopenharmony_ci    uint32_t self;           /* Structure used for alignment. */
401e41f4b71Sopenharmony_ci    uint32_t brother;        /* Structure used for alignment. */
402e41f4b71Sopenharmony_ci    uint8_t processedFlag;   /* Flag indicating whether the current node has been processed. */
403e41f4b71Sopenharmony_ci    uint8_t reserve[3];      /* Reserved for 4-byte alignment. */
404e41f4b71Sopenharmony_ci} TreeNodeInfo;
405e41f4b71Sopenharmony_ci
406e41f4b71Sopenharmony_citypedef struct {
407e41f4b71Sopenharmony_ci    TreeNodeInfo nodeInfo;   /* Data structure of each node's tree information. */
408e41f4b71Sopenharmony_ci    void *userInfo;          /* Data structure of each node's user information. */
409e41f4b71Sopenharmony_ci} TreeNode;
410e41f4b71Sopenharmony_ci```
411e41f4b71Sopenharmony_ci
412e41f4b71Sopenharmony_ciThe **TreeNode** structure has two member structures. In the following code, the address of the first member is the initial address of the second member minus the value of sizeof (the first member). (**inUserInfo** points to the **userInfo** field in the structure.)
413e41f4b71Sopenharmony_ci
414e41f4b71Sopenharmony_ci```c
415e41f4b71Sopenharmony_ciinTreeNodeInfo = (TreeNodeInfo *)((void *)(((char *)inUserInfo) - sizeof(TreeNodeInfo)));
416e41f4b71Sopenharmony_ci```
417e41f4b71Sopenharmony_ci
418e41f4b71Sopenharmony_ciThe structure adopts natural alignment. Note that the length of the substructure **TreeNodeInfo** is 12 bytes on both 32- and 64-bit OSs. On a 32-bit OS, there is no padding between member structures of the **TreeNode** structure, and the structure length is 16 bytes. On a 64-bit OS, **sizeof(TreeNodeInfo)** is 12 and **sizeof(TreeNode)** is 24, which means that there is a 4-byte padding field after the substructure **TreeNodeInfo**. Therefore, when the preceding method is used to obtain the address of the previous field on a 64-bit OS, the 4-byte padding field is not calculated, causing a member access error.
419e41f4b71Sopenharmony_ci
420e41f4b71Sopenharmony_ci#### [Rec] When defining a structure, implement 8-byte natural alignment to save storage space and avoid padding on the premise that readability is ensured.
421e41f4b71Sopenharmony_ci
422e41f4b71Sopenharmony_ci[Description] If a structure can be naturally aligned, no padding is required, which effectively reduces the invalid space of the structure. You are advised to define 64-bit data types such as size_t and pointer at both ends of the structure without affecting readability.
423e41f4b71Sopenharmony_ci
424e41f4b71Sopenharmony_ci[Example]
425e41f4b71Sopenharmony_ci
426e41f4b71Sopenharmony_ci```c
427e41f4b71Sopenharmony_ci// The length of the following structure is 24 bytes in natural alignment mode.
428e41f4b71Sopenharmony_cistruct Foo
429e41f4b71Sopenharmony_ci{
430e41f4b71Sopenharmony_ci    int32_t a;
431e41f4b71Sopenharmony_ci    uint64_t l;
432e41f4b71Sopenharmony_ci    int32_t x;
433e41f4b71Sopenharmony_ci}
434e41f4b71Sopenharmony_ci
435e41f4b71Sopenharmony_ci// After proper adjustment, the size can be reduced to 16 bytes.
436e41f4b71Sopenharmony_cistruct Foo
437e41f4b71Sopenharmony_ci{
438e41f4b71Sopenharmony_ci    uint64_t l;
439e41f4b71Sopenharmony_ci    int32_t a;
440e41f4b71Sopenharmony_ci    int32_t x;
441e41f4b71Sopenharmony_ci}
442e41f4b71Sopenharmony_ci```
443e41f4b71Sopenharmony_ci
444e41f4b71Sopenharmony_ci### Data Type Conversion and Calculation
445e41f4b71Sopenharmony_ci
446e41f4b71Sopenharmony_ci#### [Rule] Avoid implicit type conversion between different data types. If necessary, use explicit type conversion to avoid result inconsistency between the 32- and 64-bit environments.
447e41f4b71Sopenharmony_ci
448e41f4b71Sopenharmony_ci[Description] Exercise caution when performing operations between operands with different lengths and precisions. Pay attention to the following about implicit type conversion:
449e41f4b71Sopenharmony_ci
450e41f4b71Sopenharmony_ci1. When the value of a 64-bit variable is assigned to a 32-bit variable, the values of the least significant 32 bits are directly assigned, and the values of the most significant 32 bits are ignored. Then the least significant 32 bits are treated as signed or unsigned based on the left value variable type.
451e41f4b71Sopenharmony_ci
452e41f4b71Sopenharmony_ci2. When the value of a 32-bit variable is assigned to a 64-bit variable, sign extension is performed based on whether the 32-bit variable is signed or unsigned, and then the 64-bit variable is treated as signed or unsigned based on the variable type.
453e41f4b71Sopenharmony_ci
454e41f4b71Sopenharmony_ci3. For operations of signed and unsigned numbers, if the result type is not specified, the result is treated as unsigned by default.
455e41f4b71Sopenharmony_ci
456e41f4b71Sopenharmony_ciThe preceding conversion process may cause unexpected results. Therefore, exercise caution to avoid implicit type conversion as much as possible.
457e41f4b71Sopenharmony_ci
458e41f4b71Sopenharmony_ci[Example] Example of the correct conversion result
459e41f4b71Sopenharmony_ci
460e41f4b71Sopenharmony_ci```c
461e41f4b71Sopenharmony_ciint32_t t1 = -2;
462e41f4b71Sopenharmony_ciint64_t t2 = 1;
463e41f4b71Sopenharmony_ciint32_t t3 = t1 + t2;
464e41f4b71Sopenharmony_ciprintf("t3 = %d\n", t3);
465e41f4b71Sopenharmony_ci
466e41f4b71Sopenharmony_ci// Printed: t3 = -1
467e41f4b71Sopenharmony_ci```
468e41f4b71Sopenharmony_ci
469e41f4b71Sopenharmony_cit1 is a 32-bit number, and t2 is a 64-bit number. Before the calculation, t1 is extended to 64 bits. After the calculation, the result is a 64-bit int64_t type. The hexadecimal value stored in the memory is 0xffffffffffffffff. During the value assignment, the value is truncated into 0xffffffff. Then, the value is treated as signed, which is -1. Although the result is correct, data truncation occurs. This may not be the author's intention.
470e41f4b71Sopenharmony_ci
471e41f4b71Sopenharmony_ci[Example] Conversion from signed to unsigned
472e41f4b71Sopenharmony_ci
473e41f4b71Sopenharmony_ci```c
474e41f4b71Sopenharmony_ciint64_t t1 = -1;
475e41f4b71Sopenharmony_ciuint32_t t2 = t1;
476e41f4b71Sopenharmony_ciprintf("t2=%u", t2);
477e41f4b71Sopenharmony_ci
478e41f4b71Sopenharmony_ci// Printed: t2=4294967295
479e41f4b71Sopenharmony_ci```
480e41f4b71Sopenharmony_ci
481e41f4b71Sopenharmony_cit1 is a 64-bit int64_t type, which is 0xffffffffffffffff in binary mode. When this value is assigned to a 32-bit int type, the most significant 32 bits are ignored and the least significant 32 bits are displayed. The binary value is 0xffffffff, which is 4294967295 in unsigned mode.
482e41f4b71Sopenharmony_ci
483e41f4b71Sopenharmony_ci[Example] Conversion from 32-bit to unsigned 64-bit
484e41f4b71Sopenharmony_ci
485e41f4b71Sopenharmony_ci```c
486e41f4b71Sopenharmony_ciint32_t t1 = -1;
487e41f4b71Sopenharmony_ciuint64_t t2 = t1;
488e41f4b71Sopenharmony_ciprintf("t2 = %lu\n", t2);
489e41f4b71Sopenharmony_ci
490e41f4b71Sopenharmony_ci// Printed: t2 = 18446744073709551615
491e41f4b71Sopenharmony_ci```
492e41f4b71Sopenharmony_ci
493e41f4b71Sopenharmony_cit1 is a signed negative 32-bit number, which must be extended with signs. The most significant bits of the negative number are all fs, and the value after extension is 0xffffffffffffffff. t2 is an unsigned 64-bit number, the value of which is a large positive number.
494e41f4b71Sopenharmony_ci
495e41f4b71Sopenharmony_ci#### [Rule] When a pointer is used as the base address and the offset is calculated by byte, the pointer must be forcibly converted to a single-byte pointer such as uintptr_t or uint8_t \*.
496e41f4b71Sopenharmony_ci
497e41f4b71Sopenharmony_ci[Description] If the pointer is converted to an integer of the uint32_t type, the pointer may be truncated. This will not occur if the pointer is converted to uintptr_t. The pointer can also be converted to a single-byte pointer such as uint8_t \* and char \*. In this case, the offset is considered as bytes. A one-byte offset will be carried out for the void \* type. To clarify the type, you are advised to use the type that is more specific.
498e41f4b71Sopenharmony_ci
499e41f4b71Sopenharmony_ci[Example]
500e41f4b71Sopenharmony_ci
501e41f4b71Sopenharmony_ci```c
502e41f4b71Sopenharmony_ci// Incorrect
503e41f4b71Sopenharmony_civoid *pPkt = (void *)((uint32_t)MSG_GET_DATA_ADDR(msgAddr) + OFFSET);
504e41f4b71Sopenharmony_ci
505e41f4b71Sopenharmony_ci// Correct
506e41f4b71Sopenharmony_civoid *pPkt = (void *)((uintptr_t)MSG_GET_DATA_ADDR(msgAddr) + OFFSET); // C
507e41f4b71Sopenharmony_civoid *pPkt = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(MSG_GET_DATA_ADDR(msgAddr)) + OFFSET); // C++
508e41f4b71Sopenharmony_ci```
509e41f4b71Sopenharmony_ci
510e41f4b71Sopenharmony_ci#### [Rule] Mutual assignment is forbidden between pointers and uint32_t, including function parameter passing.
511e41f4b71Sopenharmony_ci
512e41f4b71Sopenharmony_ci[Description] If the variable to be defined is a length-variable pointer, use void \*. If the variable to be defined is a pointer or an integer, use uintptr_t.
513e41f4b71Sopenharmony_ci
514e41f4b71Sopenharmony_ci[Example] Conversion between pointers and integers
515e41f4b71Sopenharmony_ci
516e41f4b71Sopenharmony_ci```c
517e41f4b71Sopenharmony_ciint32_t i, *p, *q;
518e41f4b71Sopenharmony_cip = &i;
519e41f4b71Sopenharmony_ciq = (int32_t *) (int32_t)&i;
520e41f4b71Sopenharmony_ci
521e41f4b71Sopenharmony_ci// In ARM Cortex-A32, p = q; in A64-LP64, p != q
522e41f4b71Sopenharmony_ci```
523e41f4b71Sopenharmony_ci
524e41f4b71Sopenharmony_ciTo avoid this type conflict, use uintptr_t to indicate the pointer type.
525e41f4b71Sopenharmony_ci
526e41f4b71Sopenharmony_ci#### [Rule] Mutual assignment is forbidden between size_t and int32_t/uint32_t, including function parameter passing.
527e41f4b71Sopenharmony_ci
528e41f4b71Sopenharmony_ci[Description] The variable-length type cannot be forcibly converted to the 32-bit type.
529e41f4b71Sopenharmony_ci
530e41f4b71Sopenharmony_ci[Example]
531e41f4b71Sopenharmony_ci
532e41f4b71Sopenharmony_ci```c
533e41f4b71Sopenharmony_ciint32_t length = (int32_t)strlen(str); // Incorrect
534e41f4b71Sopenharmony_ci```
535e41f4b71Sopenharmony_ci
536e41f4b71Sopenharmony_cistrlen returns size_t (unsigned long in LP64). When the value is assigned to int32_t, truncation is inevitable. Generally, truncation occurs only when the length of **str** is greater than 2 GB. This is rare in programs.
537e41f4b71Sopenharmony_ci
538e41f4b71Sopenharmony_ci#### [Rule] When a large array or large `for` loop index is used on a 64-bit OS, the index type must be consistent with the subscript boundary.
539e41f4b71Sopenharmony_ci
540e41f4b71Sopenharmony_ci[Description] If a large array or large loop is used on a 64-bit OS, the index range may exceed 32 bits. In this case, the variable-length type or 64-bit type must be used to define the array subscript or loop variable to prevent full traversal failures caused by an incorrect variable range.
541e41f4b71Sopenharmony_ci
542e41f4b71Sopenharmony_ci[Example]
543e41f4b71Sopenharmony_ci
544e41f4b71Sopenharmony_ci```c
545e41f4b71Sopenharmony_ciint64_t count = BIG_NUMBER; 
546e41f4b71Sopenharmony_cifor (unsigned int index = 0; index != count; index++)
547e41f4b71Sopenharmony_ci    ... 
548e41f4b71Sopenharmony_ci```
549e41f4b71Sopenharmony_ci
550e41f4b71Sopenharmony_ciOn a 64-bit OS, int64_t is a 64-bit type, and count is a large number. unsigned int is a 32-bit type. As a result, the loop never ends. Therefore, the index type should be changed to int64_t.
551e41f4b71Sopenharmony_ci
552e41f4b71Sopenharmony_ci### Bit Field and Byte Order
553e41f4b71Sopenharmony_ci
554e41f4b71Sopenharmony_ci#### [Rule] When defining variables based on bit fields, fully consider the basic types and alignment of bit fields to avoid calculation errors in different bit widths.
555e41f4b71Sopenharmony_ci
556e41f4b71Sopenharmony_ci[Description] Consider both the width of a bit field and alignment. The structure length is different in different environments. Use the name rather than direct calculation result for the value of a bit field.
557e41f4b71Sopenharmony_ci
558e41f4b71Sopenharmony_ci#### [Rule] On a 64-bit OS, consider the length difference caused by the shift operation and the problem that the value generated after shift is implicitly extended to 64 bits.
559e41f4b71Sopenharmony_ci
560e41f4b71Sopenharmony_ci[Description] During the shift operation, check whether overflow and rewind occur. Change the data type to 32-bit to avoid result inconsistency.
561e41f4b71Sopenharmony_ci
562e41f4b71Sopenharmony_ci[Example]
563e41f4b71Sopenharmony_ci
564e41f4b71Sopenharmony_ci```c
565e41f4b71Sopenharmony_ciint64_t t = 1 << a; // Consider the size of a.
566e41f4b71Sopenharmony_ci```
567e41f4b71Sopenharmony_ci
568e41f4b71Sopenharmony_ciThe maximum value of a is 32 on a 32-bit OS and 64 on a 64-bit OS. If a is a 32-bit variable, the extension to 64 bits must also be considered.
569e41f4b71Sopenharmony_ci
570e41f4b71Sopenharmony_ci### Third-Party Libraries and Differentiated Features
571e41f4b71Sopenharmony_ci
572e41f4b71Sopenharmony_ci#### [Rule] The third-party class libraries used by a 64-bit OS must support 64-bit.
573e41f4b71Sopenharmony_ci
574e41f4b71Sopenharmony_ci[Description] Some library functions and third-party open-source code may not fully support 64-bit. You must evaluate all involved code to ensure that it can run in the 64-bit environment. Some library functions are implemented using different APIs in the 32- and 64-bit environments. Ensure that correct APIs are used.
575e41f4b71Sopenharmony_ci
576e41f4b71Sopenharmony_ci[Example] In the 32-bit environment, **mmap** can be used. If the size of the memory to map exceeds 2 GB, **mmap64** is required. In the 64-bit environment, **mmap** is used.
577e41f4b71Sopenharmony_ci
578e41f4b71Sopenharmony_ci#### [Rule] Functionalities involving bottom-layer assembly must be debugged separately on the 32- and 64-bit OSs.
579e41f4b71Sopenharmony_ci
580e41f4b71Sopenharmony_ci[Description] The number and bit width of registers are different in the 32- and 64-bit environments. The debugging functionalities related to assembly must be adjusted. You must also pay attention to the code validity in the 32-bit and 64-bit environments.
581e41f4b71Sopenharmony_ci
582e41f4b71Sopenharmony_ci[Example] For the push-to-stack functionality of the call stack, you must write and debug the assembly code in the 32- and 64-bit environment separately.
583e41f4b71Sopenharmony_ci
584e41f4b71Sopenharmony_ci#### [Rule] The patch functionality must support both 32- and 64-bit instructions.
585e41f4b71Sopenharmony_ci
586e41f4b71Sopenharmony_ci[Description] The patch mechanism and functionalities must be adopted to the command length changes.
587e41f4b71Sopenharmony_ci
588e41f4b71Sopenharmony_ci#### [Rule] All tools used on a 64-bit OS must support 64-bit.
589e41f4b71Sopenharmony_ci
590e41f4b71Sopenharmony_ci[Description] If type inconsistency is inevitable, convert the type with caution to ensure that the final result meets the application requirements.
591