Search code examples
chexvariable-assignmentqemupci

Weird register hex value 0x010000edu in QEMU edu PCI device


In the sourcecode for the QEMU edu PCI device, written in C, the following assignment is made:

val = 0x010000edu;

(also stated in the documentation).

This should be the value stored in the internal register of the device with offset 0x00 (the first one). u is not a hex value. Actually reading the contents of the register from an OS, only 0x010000ed is shown.

The above assignment val = 0x010000edu seems meaningless. Why, then, it has been made this way?


In a test program, I can make:

# include <stdio.h>
# include <inttypes.h>

void main() {
uint32_t testvalue = 0x010000edu;
printf("%08x\n", testvalue);
}

It successfully compiles and 001000ed is printed on screen. But:

uint32_t testvalue = 0x010u00ed;

would provoke a compiler error:

test.c: In function ‘main’:
test.c:9:19: error: invalid suffix "u00ed" on integer constant
    9 |  uint32_t testvalue = 0x010u00ed;
      |                       ^~~~~~~~~~

What I can not understand is why the u is not rejected in both cases, because it is not a hex digit.


Solution

  • An integer constant in C language can have a suffix, that determines/changes the type of the integer literal. See cppreference integer constant.

    Suffix u or U with an hexadecimal integer constant is used to change the type of the literal to unsigned int unsigned long int or unsigned long long int. The suffix u is used when you want to specify the type of literal to be unsigned, in this case 0x010000ed could be an int or long depending on architecture, that would undergo signed to unsigned conversion when assigning to uint32_t variable. Or someone has to follow rules, or it could serve as an documentation that the value is unsigned.

    @edit it's "integer constant" in C, "literal" in C++