简体   繁体   中英

Problem using 64 bit data in 32 bit processor (ARM Cortex A9)

First of all, context: I'm implementing a program in ARM Cortex A9 processor. I had an issue related to the C code itself which was solved here: How to set the values of an array to a single variable

First I wrote the code in my computer (OS Linux 64 bits) and the accepted answer in the above link works. However, when I did the same in the ARM A9 it didn't. I did a simple test on ARM:

uint64_t test = 0x1B26B354A1CF;
printf("%lx", test);

it prints:

d

The same in my computer:

 uint64_t test = 0x1B26B354A1CF;
 printf("%lx \n", test);

prints:

1b26b354a1cf

So it seems like an overflow problem or a problem handling that "big" data. How can I find a workaround or an alternative solution to this?

Target: ARTY Z7 FPGA (in this problem you can ignore the "FPGA" part. I'm just workint with the processor this board has: ARM A9 CORTEX)

You have two problems in your code:

  1. You don't know which suffix to use to define an uint64_t literal on your target platform.

  2. You don't know which format specifier to use in printf for uint64_t values on your target platform.

Both can be solved by using macros defined in stdint.h .

In particular, to define a literal and assign it to a variable:

uint64_t test = UINT64_C(0x1B26B354A1CF);

To print the variable's hexadecimal value in printf :

printf("%" PRIx64 "\n", test);

This is guaranteed to work on any platform that properly supports uint64_t , no matter how many bits its processor is.

While the language itself does not require you to use a suffix for integer literals in most cases - a notable exception is using a literal directly as an argument for a variadic function like printf - doing it explicitly is a good practice in general and may be mandatory in code guidelines of safety-critical projects. For example, the Rule 10.6 of MISRA C:2004 guidelines requires the use of U suffix for all unsigned constants.

For normal printf (and family) the format to print a unsigned long long (which uint64_t most likely is) in hexadecimal is "%llx" . Note the extra l size prefix.

Mismatching format specifier and argument type leads to undefined behavior .

What is most likely happening is that long is 32 bits on your 32-bit system, and 64-bits on your home system, that's why it seems to work on your home system.

With regard to the suffix for defining the unsigned 64-bit literal, you can check what suffix is used in your stdint.h for #define UINT64_MAX . In my case, a macro called __UINT64_C(c) is used to paste the suffix UL after the literal if my word size is 64, or ULL if my word size is 32.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM