Miguel Duran Diaz
Miguel Duran Diaz

Reputation: 312

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)

Upvotes: 1

Views: 1976

Answers (3)

Kit.
Kit.

Reputation: 2406

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.

Upvotes: 4

gdea73
gdea73

Reputation: 36

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.

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409206

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.

Upvotes: 1

Related Questions