void foo(double a) {
...
}
And in main()
I passed 107.0
to foo
as its parameter. Then I used gdb to examine the binary representation of a
by p /ta
, and this is what I got:
$1 = 1101011
This results seems very strange to me. This is the binary representation of INTEGER 107. But here the type of a
is defined as double
and we passed a parameter of 107.0
. And we know that doubles have different binary representations as integers.
Can anyone explain why a
has a integer binary rep rather than double? Is the compiler doing anything funny?
You told gdb to print it as a binary integer.
p /t a
If you want to see the floating point version use
p /f a
x Regard the bits of the value as an integer, and print the integer in hexadecimal.
d Print as integer in signed decimal.
u Print as integer in unsigned decimal.
o Print as integer in octal.
t Print as integer in binary. The letter `t' stands for "two". (2)
a Print as an address, both absolute in hexadecimal and as an offset from the nearest preceding symbol. You can use this format used to discover where (in what function) an unknown address is located:
c Regard as an integer and print it as a character constant.
f Regard the bits of the value as a floating point number and print using typical floating point syntax.
For example, to print the program counter in hex (see section Registers), type
p/x $pc
Doubles are represented in powers of two, just a bit different than integers. Not going into much details, 107 would be 1.101011 * (2^6) = 1101011. It is possible that gdb only shows the last result instead of giving you the full 64bit representation for no reason.
well im not familiar with gdb, but when you write "d" it might think that you explicitly mean integers
consider:
double foo = 1.0;
printf("%d",foo);
c will be confused because you tell it you will give it an integer but you actually give it a double.
There are several ways to print variables' values from the gdb command line.
print works on expressions, and will do some implicit conversions, just as C does.
p /ta
in your example will convert a's value to an integer and print it in base 2.
You wanted to look at a
's bit pattern, so there are a few options with print
:
unsigned long long
or uint64_t
in your example - and dereference that. (gdb) p /t *(uint64_t *)&a
$6 = 100000001011010110000000000000000000000000000000000000000000000
{uint64_t}
to accomplish the same thing more concisely. (gdb) p /t {uint64_t}&a
$7 = 100000001011010110000000000000000000000000000000000000000000000
x displays the data at a given address, and you can specify the datatype. /g
means an 8-byte integer.
(gdb) x /tg &a
0x7fffffffded8: 0100000001011010110000000000000000000000000000000000000000000000
If you use optimization, it's possible that a
will be in a register, and you won't be able to take its address, so none of the above will work.
(gdb) p {uint64_t}&a
Address requested for identifier "a" which is in register $ymm0
But gdb
supports printing the contents of AVX registers in various formats, using syntax resembling a C union of arrays.
(gdb) p $ymm0
$1 = {v8_float = {0, 3.41796875, 0, 0, 0, 0, 0, 0},
v4_double = {107, 0, 0, 0}, v32_int8 = {0, 0, 0, 0, 0, -64, 90,
64, 0 <repeats 24 times>},
v16_int16 = {0, 0, -16384, 16474, 0 <repeats 12 times>},
v8_int32 = {0, 1079689216, 0, 0, 0, 0, 0, 0},
v4_int64 = {4637229872563879936, 0, 0, 0},
v2_int128 = {0x0000000000000000405ac00000000000, 0x00000000000000000000000000000000}}
(gdb) p /t $ymm0.v4_int64[0]
$2 = 100000001011010110000000000000000000000000000000000000000000000
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.