Reputation: 965
At this simple C99-Code:
int main(void){
int a[3][3] = {1};
int m = 3;
int x;
int b[m][m];
x = sizeof(b);
b[0][0] = -1;
return 0;
}
with GDB we set a breakpoint at the return line and run. Now let's look at the following:
(gdb) p a
$1 = {{1, 0, 0}, {0, 0, 0}, {0, 0, 0}}
(gdb) p b
$2 = 0x7fffffffe3a0
(gdb) p sizeof(a)
$3 = 36
(gdb) p sizeof(b)
$4 = 0
(gdb) p x
$5 = 36
(gdb) whatis a
type = int [3][3]
(gdb) whatis b
type = int [][]
(gdb)
I wonder how this does happen. The C runtime environment assumes that the type of b is int [3][3]
(because sizeof(b)
is 36), but GDB does not.
Upvotes: 2
Views: 544
Reputation: 37914
The most obvious explanation would be that you have entered into main
, but apparently have not reached VLA declaration.
To cover this, the C11 (N1570) §6.2.4/7 Storage durations of objects states that (emphasis mine):
For such an object that does have a variable length array type, its lifetime extends from the declaration of the object until execution of the program leaves the scope of the declaration.35)
The remedy is to step up into the declaration of VLA (tested with gcc 4.4.7 and gdb 7.2):
Breakpoint 1, main () at so.c:1
1 int main(void){
(gdb) s
2 int a[3][3] = {1};
(gdb) s
3 int m = 3;
(gdb) s
5 int b[m][m];
(gdb) s
6 x = sizeof(b);
(gdb) p b
$5 = {{-1207961984, 0, 1114472}, {6381016, 6319652, -1073745804}, {6416216, 14, 129100401}}
gdb) whatis b
type = int [variable][variable]
It may be also a discrepancy between gdb
versions or some sort of bug, though the latter is always the last thing to consider.
EDIT:
I have build gdb 7.7 (CentOS 6.8 32-bit) from source and it displays the address of b
instead of array content, so I confirm that issue is with this specific version and consider it has a potential bug or misfeature.
On the other hand, the latest version 7.11 behaves correctly.
GDB 7.7
[grzegorz@centos workspace]$ gdb-7.7/gdb/gdb -q a.out
Reading symbols from a.out...done.
(gdb) b main
Breakpoint 1 at 0x80483ab: file so.c, line 1.
(gdb) r
Starting program: /home/grzegorz/workspace/a.out
Breakpoint 1, main () at so.c:1
1 int main(void){
(gdb) s
2 int a[3][3] = {1};
(gdb) s
3 int m = 3;
(gdb)
5 int b[m][m];
(gdb)
6 x = sizeof(b);
(gdb) p b
$1 = 0xbffff0c0
GDB 7.11
[grzegorz@centos workspace]$ gdb-7.11/gdb/gdb -q a.out
Reading symbols from a.out...done.
(gdb) b main
Breakpoint 1 at 0x80483ab: file so.c, line 1.
(gdb) r
Starting program: /home/grzegorz/workspace/a.out
Breakpoint 1, main () at so.c:1
1 int main(void){
(gdb) s
2 int a[3][3] = {1};
(gdb)
3 int m = 3;
(gdb)
5 int b[m][m];
(gdb)
6 x = sizeof(b);
(gdb) p b
$1 = {{-1207961984, 0, 1114472}, {6381016, 6319652, -1073745676}, {6416216, 14, 129100401}}
Moral story: Either upgrade or downgrade your version of gdb
to get correct behaviour
Upvotes: 5