* Printing a 2D array in a C program
@ 2016-03-04 14:27 Neven Sajko
2016-03-04 14:42 ` Jan Kratochvil
0 siblings, 1 reply; 12+ messages in thread
From: Neven Sajko @ 2016-03-04 14:27 UTC (permalink / raw)
To: gdb
Hello,
I have a newbie question.
GDB version is 7.11, compiler is gcc 5.3.0 (-std=gnu90).
In my C program there is a square matrix implemented as an array
of arrays, which prints nicely in GDB with `info locals`.
But how can that nice output be accomplished if you are not in
the function in which the array was declared, but just have it
passed as a function parameter.
Thank you,
Neven
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: Printing a 2D array in a C program 2016-03-04 14:27 Printing a 2D array in a C program Neven Sajko @ 2016-03-04 14:42 ` Jan Kratochvil 2016-03-04 16:15 ` Neven Sajko 0 siblings, 1 reply; 12+ messages in thread From: Jan Kratochvil @ 2016-03-04 14:42 UTC (permalink / raw) To: Neven Sajko; +Cc: gdb On Fri, 04 Mar 2016 15:27:14 +0100, Neven Sajko wrote: > In my C program there is a square matrix implemented as an array > of arrays, which prints nicely in GDB with `info locals`. I do not understand how that can happen. You should always provide sample code / example. > But how can that nice output be accomplished if you are not in > the function in which the array was declared, but just have it > passed as a function parameter. If it is a pointer (as you say C, not C++ reference) you should be able to: (gdb) print *thatpointername Then GDB should IMO print it the same as a local variable is printed. Printing of C++ vectors of vectors (which is BTW wrong data structure for a 2D matrix anyway) as a matrix was implemented by Chris Moller as a Python Pretty printer in some versions of Fedora GDB but it was later discontinued. The initial implementation was: http://pkgs.fedoraproject.org/cgit/rpms/gdb.git/commit/?id=6068e6305ed7d05b4a919c28aa5bcb737e1f163b (gdb) p test2 $2 = { {0 1 } {2 3 } {4 5 } } Jan ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Printing a 2D array in a C program 2016-03-04 14:42 ` Jan Kratochvil @ 2016-03-04 16:15 ` Neven Sajko 2016-03-04 17:49 ` Jan Kratochvil 2016-03-04 18:34 ` Andreas Schwab 0 siblings, 2 replies; 12+ messages in thread From: Neven Sajko @ 2016-03-04 16:15 UTC (permalink / raw) To: Jan Kratochvil; +Cc: gdb On 4 March 2016 at 15:42, Jan Kratochvil <jan.kratochvil@redhat.com> wrote: > On Fri, 04 Mar 2016 15:27:14 +0100, Neven Sajko wrote: >> In my C program there is a square matrix implemented as an array >> of arrays, which prints nicely in GDB with `info locals`. > > I do not understand how that can happen. > You should always provide sample code / example. > > >> But how can that nice output be accomplished if you are not in >> the function in which the array was declared, but just have it >> passed as a function parameter. > > If it is a pointer (as you say C, not C++ reference) you should be able to: > (gdb) print *thatpointername > Then GDB should IMO print it the same as a local variable is printed. > > > Printing of C++ vectors of vectors (which is BTW wrong data structure for a 2D > matrix anyway) as a matrix was implemented by Chris Moller as a Python Pretty > printer in some versions of Fedora GDB but it was later discontinued. The > initial implementation was: > http://pkgs.fedoraproject.org/cgit/rpms/gdb.git/commit/?id=6068e6305ed7d05b4a919c28aa5bcb737e1f163b > (gdb) p test2 > $2 = > { > {0 1 } > {2 3 } > {4 5 } > } > > > > Jan Thanks for your answer, Jan. In my question I asked about C (not C++), I even mentioned the gcc -std=gnu90 option. My code is thus: enum { sz = 17 }; void p(int m[sz][sz], int n) { int i; for (i=1; i<n; i++) { int j; for (j=i-1; 0<=j; j--) { m[i][j] = abs(3*m[i-1][j] +2*m[i][j+1]) % 9340506; } } } void f(int n) { int m[sz][sz]; g(m, n); p(m, n); r(m, n); } So, when I am in f, `info locals` prints it like {{a11, ..., a1n}, ..., {an1, ..., ann}}. But in p `print *m` just gets me {a11, ..., a1n}. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Printing a 2D array in a C program 2016-03-04 16:15 ` Neven Sajko @ 2016-03-04 17:49 ` Jan Kratochvil 2016-03-04 18:24 ` Pedro Alves 2016-03-04 18:34 ` Andreas Schwab 1 sibling, 1 reply; 12+ messages in thread From: Jan Kratochvil @ 2016-03-04 17:49 UTC (permalink / raw) To: Neven Sajko; +Cc: gdb [-- Attachment #1: Type: text/plain, Size: 2173 bytes --] On Fri, 04 Mar 2016 17:15:26 +0100, Neven Sajko wrote: > But in p `print *m` just gets me {a11, ..., a1n}. I think it is a bug in GCC. I haven't found it in GCC Bugzilla. I haven't filed it anywhere yet. All these compilers fail the same way: gcc-5.3.1-2.fc23.x86_64 gcc-6.0.0-0.13.fc25.x86_64 gcc (GCC) 6.0.0 20160213 (experimental) clang-3.7.0-4.fc23.x86_64 clang-3.8.0-0.3.fc25.x86_64 The .s diff is for: gcc -o matrix.s matrix.c -Wall -g -S -dA Jan The array variable: (gdb) s f (n=1) at matrix2.c:22 (gdb) ptype m type = int [17][17] (gdb) p m $1 = {{-134241616, 32767, -134252848, 32767, -140382932, 32767, 2224, 0, -134252032, 32767, -136422399, 32767, 2224, 0, -140329216, 32767, -134252112}, {32767, -134252032, 32767, -11384, 32767, -11388, 32767, 1, 0, -136460380, 32767, -140329216, 32767, [...] -10400, 32767, -134225592, 32767, 0, 0, 1, 0, 4195965, 0, 4195328, 0, 0, 0, 4195888}} The bug with the parameter: (gdb) s p (m=0x7fffffffd2a0, n=1) at matrix2.c:9 (gdb) ptype m type = int (*)[17] (gdb) p m $2 = (int (*)[17]) 0x7fffffffd2a0 (gdb) p *m $3 = {-134241616, 32767, -134252848, 32767, -140382932, 32767, 2224, 0, -134252032, 32767, -136422399, 32767, 2224, 0, -140329216, 32767, -134252112} Workaroundable by: (gdb) p *(int[17][17] *)m $4 = {{-134241616, 32767, -134252848, 32767, -140382932, 32767, 2224, 0, -134252032, 32767, -136422399, 32767, 2224, 0, -140329216, 32767, -134252112}, {32767, -134252032, 32767, -11384, 32767, -11388, 32767, 1, 0, -136460380, 32767, -140329216, 32767, [...] -10400, 32767, -134225592, 32767, 0, 0, 1, 0, 4195965, 0, 4195328, 0, 0, 0, 4195888}} After fixed DWARF without the workaround: (gdb) s p (m=0x7fffffffd2a0, n=1) at matrix2.c:9 (gdb) ptype m type = int (*)[17][17] (gdb) p m $1 = (int (*)[17][17]) 0x7fffffffd2a0 (gdb) p *m $2 = {{-134241616, 32767, -134252848, 32767, -140382932, 32767, 2224, 0, -134252032, 32767, -136422399, 32767, 2224, 0, -140329216, 32767, -134252112}, {32767, -134252032, 32767, -11384, 32767, -11388, 32767, 1, 0, -136460380, 32767, -140329216, 32767, [...] -10400, 32767, -134225592, 32767, 0, 0, 1, 0, 4195965, 0, 4195328, 0, 0, 0, 4195888}} [-- Attachment #2: Fix of the DWARF --] [-- Type: text/plain, Size: 403 bytes --] --- matrix2.s-orig 2016-03-04 18:30:45.846203946 +0100 +++ matrix2.s 2016-03-04 18:33:33.912409159 +0100 @@ -329,7 +329,7 @@ main: .byte 0 # end of children of DIE 0xf1 .uleb128 0xc # (DIE (0x101) DW_TAG_pointer_type) .byte 0x8 # DW_AT_byte_size - .long 0xf1 # DW_AT_type + .long 0x13d # DW_AT_type .uleb128 0xd # (DIE (0x107) DW_TAG_subprogram) # DW_AT_external .ascii "f\0" # DW_AT_name [-- Attachment #3: Effect of the DWARF fix --] [-- Type: text/plain, Size: 1488 bytes --] <2><ae>: Abbrev Number: 7 (DW_TAG_formal_parameter) <af> DW_AT_name : m <b1> DW_AT_decl_file : 1 <b2> DW_AT_decl_line : 7 <b3> DW_AT_type : <0x101> <b7> DW_AT_location : 2 byte block: 91 58 (DW_OP_fbreg: -40) <1><f1>: Abbrev Number: 10 (DW_TAG_array_type) <f2> DW_AT_type : <0x34> <f6> DW_AT_sibling : <0x101> <2><fa>: Abbrev Number: 11 (DW_TAG_subrange_type) <fb> DW_AT_type : <0x65> <ff> DW_AT_upper_bound : 16 <2><100>: Abbrev Number: 0 <1><101>: Abbrev Number: 12 (DW_TAG_pointer_type) <102> DW_AT_byte_size : 8 - <103> DW_AT_type : <0xf1> + <103> DW_AT_type : <0x13d> <1><107>: Abbrev Number: 13 (DW_TAG_subprogram) <2><12f>: Abbrev Number: 8 (DW_TAG_variable) <130> DW_AT_name : m <132> DW_AT_decl_file : 1 <133> DW_AT_decl_line : 18 <134> DW_AT_type : <0x13d> <138> DW_AT_location : 3 byte block: 91 e0 76 (DW_OP_fbreg: -1184) <2><13c>: Abbrev Number: 0 <1><13d>: Abbrev Number: 10 (DW_TAG_array_type) <13e> DW_AT_type : <0x34> <142> DW_AT_sibling : <0x153> <2><146>: Abbrev Number: 11 (DW_TAG_subrange_type) <147> DW_AT_type : <0x65> <14b> DW_AT_upper_bound : 16 <2><14c>: Abbrev Number: 11 (DW_TAG_subrange_type) <14d> DW_AT_type : <0x65> <151> DW_AT_upper_bound : 16 <2><152>: Abbrev Number: 0 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Printing a 2D array in a C program 2016-03-04 17:49 ` Jan Kratochvil @ 2016-03-04 18:24 ` Pedro Alves 2016-03-04 18:59 ` Jan Kratochvil 0 siblings, 1 reply; 12+ messages in thread From: Pedro Alves @ 2016-03-04 18:24 UTC (permalink / raw) To: Jan Kratochvil, Neven Sajko; +Cc: gdb On 03/04/2016 05:48 PM, Jan Kratochvil wrote: > The bug with the parameter: > (gdb) s > p (m=0x7fffffffd2a0, n=1) at matrix2.c:9 > (gdb) ptype m > type = int (*)[17] > (gdb) p m > $2 = (int (*)[17]) 0x7fffffffd2a0 > (gdb) p *m > $3 = {-134241616, 32767, -134252848, 32767, -140382932, 32767, 2224, 0, -134252032, 32767, -136422399, 32767, 2224, 0, -140329216, > 32767, -134252112} It's a C gotcha, but I don't think it's a bug. Essentially, a parameter declared as an array is really treated as a pointer parameter. From http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf: " 6.7.5.3 Function declarators (including prototypes) Constraints (...) 7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’ (...) " So the DWARF describes the type as really what is is. See: ~~~~~~~~~~~~~~~~ $ cat array-param.c #include <stdlib.h> #include <stdio.h> enum { sz = 17 }; void p (int m[sz][sz]) { printf ("m: sizeof m = %d\n", (int) sizeof (m)); } void f (void) { int m[sz][sz]; printf ("f: sizeof m = %d\n", (int) sizeof (m)); p (m); } int main () { f (); return 0; } $ gcc -v gcc version 6.0.0 20160301 (experimental) (GCC) $ gcc array-param.c -o array-param -Wall -Wextra -O2 array-param.c: In function ‘p’: array-param.c:12:46: warning: ‘sizeof’ on array function parameter ‘m’ will return size of ‘int (*)[17]’ [-Wsizeof-array-argument] printf ("m: sizeof m = %d\n", (int) sizeof (m)); ^ array-param.c:10:8: note: declared here p (int m[sz][sz]) ^ $ ./array-param f: sizeof m = 1156 m: sizeof m = 8 ~~~~~~~~~~~~~~~~ Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Printing a 2D array in a C program 2016-03-04 18:24 ` Pedro Alves @ 2016-03-04 18:59 ` Jan Kratochvil 2016-03-04 19:16 ` Pedro Alves 0 siblings, 1 reply; 12+ messages in thread From: Jan Kratochvil @ 2016-03-04 18:59 UTC (permalink / raw) To: Pedro Alves; +Cc: Neven Sajko, gdb On Fri, 04 Mar 2016 19:24:19 +0100, Pedro Alves wrote: > It's a C gotcha, but I don't think it's a bug. Essentially, a parameter > declared as an array is really treated as a pointer parameter. I did not look it up but I expected the standard probably says something like that, this is also why clang matches the gcc behavior. But GDB could try to be more helpful displaying the data. For example DWARF could have the pointer there at its type for sizeof and similar but additionally there could be some new GNU attribute for printing the data. Just I did not file it as I think C++ is more appropriate for such (or all) cases where it already just works. Jan ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Printing a 2D array in a C program 2016-03-04 18:59 ` Jan Kratochvil @ 2016-03-04 19:16 ` Pedro Alves 0 siblings, 0 replies; 12+ messages in thread From: Pedro Alves @ 2016-03-04 19:16 UTC (permalink / raw) To: Jan Kratochvil; +Cc: Neven Sajko, gdb On 03/04/2016 06:59 PM, Jan Kratochvil wrote: > On Fri, 04 Mar 2016 19:24:19 +0100, Pedro Alves wrote: >> It's a C gotcha, but I don't think it's a bug. Essentially, a parameter >> declared as an array is really treated as a pointer parameter. > > I did not look it up but I expected the standard probably says something like > that, It's in the url/paste I showed. C99, 6.7.5.3, point 7. > For example DWARF could have the pointer > there at its type for sizeof and similar but additionally there could be some > new GNU attribute for printing the data. Yeah, might be a good idea. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Printing a 2D array in a C program 2016-03-04 16:15 ` Neven Sajko 2016-03-04 17:49 ` Jan Kratochvil @ 2016-03-04 18:34 ` Andreas Schwab 2016-03-04 21:48 ` Neven Sajko 1 sibling, 1 reply; 12+ messages in thread From: Andreas Schwab @ 2016-03-04 18:34 UTC (permalink / raw) To: Neven Sajko; +Cc: Jan Kratochvil, gdb Neven Sajko <nsajko@gmail.com> writes: > In my question I asked about C (not C++), I even mentioned the > gcc -std=gnu90 option. > > My code is thus: > > enum { > sz = 17 > }; > > void p(int m[sz][sz], int n) { > int i; > for (i=1; i<n; i++) { > int j; > for (j=i-1; 0<=j; j--) { > m[i][j] = abs(3*m[i-1][j] +2*m[i][j+1]) % 9340506; > } > } > } > > void f(int n) { > int m[sz][sz]; > > g(m, n); > > p(m, n); > > r(m, n); > } > > > So, when I am in f, `info locals` prints it like {{a11, ..., > a1n}, ..., {an1, ..., ann}}. > But in p `print *m` just gets me {a11, ..., a1n}. This is correct, *m has the type int[sz]. If you want to print all elements pointed to by m you need to use `print *m@sz'. Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Printing a 2D array in a C program 2016-03-04 18:34 ` Andreas Schwab @ 2016-03-04 21:48 ` Neven Sajko 2016-03-04 22:16 ` Andreas Schwab 0 siblings, 1 reply; 12+ messages in thread From: Neven Sajko @ 2016-03-04 21:48 UTC (permalink / raw) To: Andreas Schwab; +Cc: Jan Kratochvil, gdb On 4 March 2016 at 19:34, Andreas Schwab <schwab@linux-m68k.org> wrote: > This is correct, *m has the type int[sz]. If you want to print all > elements pointed to by m you need to use `print *m@sz'. > > Andreas. > > -- > Andreas Schwab, schwab@linux-m68k.org > GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 > "And now for something completely different." Thank you :) But it seems `print *m@(int)sz' is needed because enum aren't integral types? ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Printing a 2D array in a C program 2016-03-04 21:48 ` Neven Sajko @ 2016-03-04 22:16 ` Andreas Schwab 2016-03-05 0:59 ` Neven Sajko 0 siblings, 1 reply; 12+ messages in thread From: Andreas Schwab @ 2016-03-04 22:16 UTC (permalink / raw) To: Neven Sajko; +Cc: Jan Kratochvil, gdb Neven Sajko <nsajko@gmail.com> writes: > But it seems `print *m@(int)sz' is needed because enum aren't integral types? An enum constant has type int. Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Printing a 2D array in a C program 2016-03-04 22:16 ` Andreas Schwab @ 2016-03-05 0:59 ` Neven Sajko 2016-03-05 8:23 ` Andreas Schwab 0 siblings, 1 reply; 12+ messages in thread From: Neven Sajko @ 2016-03-05 0:59 UTC (permalink / raw) To: Andreas Schwab; +Cc: Jan Kratochvil, gdb On 4 March 2016 at 23:16, Andreas Schwab <schwab@linux-m68k.org> wrote: > Neven Sajko <nsajko@gmail.com> writes: > >> But it seems `print *m@(int)sz' is needed because enum aren't integral types? > > An enum constant has type int. > > Andreas. > > -- > Andreas Schwab, schwab@linux-m68k.org > GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 > "And now for something completely different." I know but if I try to do it without the cast, GDB complains that the right operand to the artificial array operator is not an integral type. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Printing a 2D array in a C program 2016-03-05 0:59 ` Neven Sajko @ 2016-03-05 8:23 ` Andreas Schwab 0 siblings, 0 replies; 12+ messages in thread From: Andreas Schwab @ 2016-03-05 8:23 UTC (permalink / raw) To: Neven Sajko; +Cc: Jan Kratochvil, gdb Neven Sajko <nsajko@gmail.com> writes: > I know but if I try to do it without the cast, GDB complains > that the right operand to the artificial array operator is not > an integral type. That looks like a bug. Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2016-03-05 8:23 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-03-04 14:27 Printing a 2D array in a C program Neven Sajko 2016-03-04 14:42 ` Jan Kratochvil 2016-03-04 16:15 ` Neven Sajko 2016-03-04 17:49 ` Jan Kratochvil 2016-03-04 18:24 ` Pedro Alves 2016-03-04 18:59 ` Jan Kratochvil 2016-03-04 19:16 ` Pedro Alves 2016-03-04 18:34 ` Andreas Schwab 2016-03-04 21:48 ` Neven Sajko 2016-03-04 22:16 ` Andreas Schwab 2016-03-05 0:59 ` Neven Sajko 2016-03-05 8:23 ` Andreas Schwab
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox