I have the following piece of simple C code where I simply try to assign a 64-bit value to uint64_t. However, the assignment happens as 32-bit value only and the most significant 32-bit are always zero. Not sure, what I am missing.
/*
C code : Temp.c
*/
#include "stdio.h"
#include <stdint.h>
int main() {
uint64_t a64 = 0x100000000UL;
printf("Size of a64 = %0d.\n", sizeof(a64));
printf("a64 = %16.16x. \n", a64);
return 0;
}
/*
//Output
Size of a64 = 8.
a64 = 0000000000000000.
*/
I tried to compile code using the blow options, but output remained the same.
- gcc Temp.c
- gcc -std=c99 Temp.c
- gcc -m64 Temp.c
I also checked the gcc version, it is 64-bit. Not sure what is wrong.
You are wrong. The initialization of the variable
a64is correct. The integer constant0x100000000ULhas an appropriate unsigned integer type that allows to store such an unsigned value. Its type eitherunsigned long(if objects of this type can accomodate such a value) orunsigned long long.For example in systems (as MS Visual Studio) where
sizeof( unsigned long int )is equal to4the type of the constant isunsigned long long intWhile in systems wheresizeof( unsigned long int )is equal to8the type of the constant isunsigned long int.If the integer constant cannot be represented by any of the mentioned above types it may have an extended integer type, if the extended integer type can represent its value. And it is evident that in any case the constant may be represented in an object of the extended type
uint64_t. So there is neither lost of data. The declarationis correct and does not require any changes.
The problem with your program is that you are using incorrect conversion specifiers in calls of
printf.For example to output a value of the type
size_tyou need to use conversion specifierzuinstead ofdand to output a value of the typeuint64_tyou need to use macros defined in header<inttypes.h>.Here is your updated program.
The program output is
Edit: I think it will be reasonable to comment the incorrect answer of
@Lundinthat was upvoted even two times while my answer was down-voted.:) Otherwise these estimations of the answers will only confuse readers of the question.He wrote
That is entirely wrong. The type of the constant
0x100000000ULis implementation defined as I pointed out in my answer. It can be eitherunsigned long intprovided that the constant can be represented in an object of that type orunsigned long long intor even some extented integer type if neither type,unsigned long intorunsigned long long int, can represent the constant.All this is described in the C Standard in the section 6.4.4.1 Integer constants.
and for the suffixes "both u or U and l or L" the corresponding types for a hexadecimal constant are
And below in the same section of the C Standard there is written:
For example try the C++ demonstration program shown below. It is a C++ program because using C++ it is easy to determine the type of an expression.
If to run the program using MS Visual Studio the output might look like
As it is seen in the environment of MS Visual Studio the constant has the type
unsigned long long intbecause the typeunsigned long intis unable to represent the constant.He also wrote in his answer that it is not guaranteed that the size of the type of the constant will be the same as the size of the type
uint64_t. But it entirely does not matter. The constant in any case can be represented in the typeuint64_t.So this declaration
is valid and is not required to be changed though one could write for example like using only suffux
U(the compiler itself will correctly determine the type of the unsigned constant)or
taking into account that if the constant in the used system has the type
unsigned long intthen moreover it can be represented as having the typeunsigned long long int. What is important in this declaration is the type of the variablea64that in any case can represent the constant.Using the macro
UINT64_Cin the declaration of the variablea64as it is proposed by@Lundinonly makes the code more complicated and confuses readers of the code. Using this macro would make sense if for example the constant needs to be outputted for example with function
printfas a value of the typeuint64_t. But in the shown program that is not required. There is outputted the variablea64that already has the concrete typeuint64_t.