![]() |
[MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?
Hi,
I'm looking for the reason of the MUDFLAP violation on my 'BIG' C project (no possibility to show), system: Ubuntu:12.04, gcc:4.6.3. NOTE: The same 'BIG' project has been successfully executed on my old system: Ubuntu:10.04, gcc-(version don't remember). Mudflap was silent. My investigation shows that there are called some functions before 'main', like: _GLOBAL__sub_I_00099_0_<org_fun_name> Currently MUDFLAP violates before calling 'main' in _GLOBAL__sub_I_00099_0_<my_function> if I change source code of <my_function> from sizeof(*ARRAY) to sizeof(ARRAY[0]) then violation source shifts to another _GLOBAL__sub_I_00099_0_... function. But this algoritm failed in case MUDFLAP violates at function that has no usage of sizeof(ARRAY) operator. Common for the all functions that MUDFLAP violates is the static const ARRAY usage, example: /*--EXAMPLE-BEG----------------*/ 01: extern unsigned my_function_check(unsigned a, unsigned b, unsigned c); 02: void my_function(void) 03: { 04: unsigned const SCALE [] = { 0, 1, 2 }; 05: unsigned const TOSTEP [][2] = { 06: { 10, 1}, 07: { 100, 8} 08: }; 09: unsigned s = sizeof(SCALE) / sizeof(SCALE[0]); 10: while (s--) 11: { 12: unsigned i = 0; 13: while (i < (sizeof(TOSTEP) / sizeof(TOSTEP[0]))) 14: { 15: unsigned current = 0; 16: unsigned value = 0; 17: current = my_function_check(SCALE[s], TOSTEP[i][0], value); 18: if (current) 19: { 20: return; 21: } 22: ++i; 23: } 24: } 25: } /*--EXAMPLE-BEG----------------*/ In this example I have not found any reason of violate before calling the main. There is amazing difference that depends on usage of the sizeof operator: --[TEST-BEG]------------------------------ + uname -a Linux ldrlinux 3.2.0-35-generic-pae #55-Ubuntu SMP Wed Dec 5 18:04:39 UTC 2012 i686 i686 i386 GNU/Linux + gcc --version gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 Copyright (C) 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + gawk '{printf("%02u: %s\n", NR, $0);}' + cat bar.c 01: #include <stddef.h> /* size_t */ 02: static int const BAR [] = {0,1,2,3,4}; 03: size_t bar_element_sizeof(void) { 04: #if ASTERISK 05: return sizeof(*BAR); 06: #else 07: return sizeof(BAR[0]); 08: #endif 09: } + gcc -W -Wall -ansi -pedantic -Werror -fmudflap -DnotASTERISK -c bar.c -o bar_notASTERISK.o + gcc -W -Wall -ansi -pedantic -Werror -fmudflap -DASTERISK -c bar.c -o bar_ASTERISK.o + objdump -d bar_notASTERISK.o + objdump -d bar_ASTERISK.o + diff bar_notASTERISK.S bar_ASTERISK.S 2c2 < bar_notASTERISK.o: file format elf32-i386 --- > bar_ASTERISK.o: file format elf32-i386 17c17 < d: 83 ec 08 sub $0x8,%esp --- > d: 83 ec 18 sub $0x18,%esp 19,20c19,28 < 15: c9 leave < 16: c3 ret --- > 15: c7 44 24 0c 14 00 00 movl $0x14,0xc(%esp) > 1c: 00 > 1d: c7 44 24 08 04 00 00 movl $0x4,0x8(%esp) > 24: 00 > 25: c7 44 24 04 14 00 00 movl $0x14,0x4(%esp) > 2c: 00 > 2d: c7 04 24 00 00 00 00 movl $0x0,(%esp) > 34: e8 fc ff ff ff call 35 <_GLOBAL__sub_I_00099_0_bar_element_sizeof+0x2b> > 39: c9 leave > 3a: c3 ret --[TEST-EOF]------------------------------ Is there any clear reason of such difference ? Best Regards -- Maciek |
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?
On 01/09/2013 10:26 AM, m.labanowicz@gmail.com wrote:
.... > + cat bar.c > 01: #include <stddef.h> /* size_t */ > 02: static int const BAR [] = {0,1,2,3,4}; > 03: size_t bar_element_sizeof(void) { > 04: #if ASTERISK > 05: return sizeof(*BAR); > 06: #else > 07: return sizeof(BAR[0]); > 08: #endif > 09: } > + gcc -W -Wall -ansi -pedantic -Werror -fmudflap -DnotASTERISK -c bar.c -o bar_notASTERISK.o > + gcc -W -Wall -ansi -pedantic -Werror -fmudflap -DASTERISK -c bar.c -o bar_ASTERISK.o > + objdump -d bar_notASTERISK.o > + objdump -d bar_ASTERISK.o As far as C is concerned, with the above definition for BAR, sizeof(*BAR) and sizeof(BAR[0]) are exactly equivalent (and the parentheses are unnecessary). As implied by the extensive use of "mudflap" and "MUDFLAP" throughout your message, this is a problem specific to gcc's -fmudflap option - without that option, gcc generates identical object code whether or not ASTERISK is #defined. Therefore, the best place to get answers to this question are on a forum specific to gcc. I don't know the answer. -- James Kuyper |
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?
On 1/9/2013 10:26 AM, m.labanowicz@gmail.com wrote:
> I'm looking for the reason of the MUDFLAP violation > on my 'BIG' C project (no possibility to show), > system: Ubuntu:12.04, gcc:4.6.3. I don't have mudflap available and can't help with it, so my comments are limited to the C aspects of the question. I hope they may be of some help anyhow ... > Currently MUDFLAP violates before calling 'main' in > _GLOBAL__sub_I_00099_0_<my_function> Are you sure this is a C program, and not a C++ program? In a C program, there's no way for any of your own code to run before main() is called, whereas in C++ some of your code may run during pre-main() initialization. I suppose the mudflap instrumentation might do some non-C-ish things, but ... > if I change source code of <my_function> > from sizeof(*ARRAY) > to sizeof(ARRAY[0]) > then violation source shifts to another > _GLOBAL__sub_I_00099_0_... function. From the perspective of the C language, the two expressions have identical meaning. That's because of the way C defines the array subscript operator, in 6.5.2.1p2: "The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))." In your case `E1' and `E2' are `ARRAY' and `0', so your second expression is identical to `sizeof((*((ARRAY)+(0))))', which is equivalent to `sizeof *ARRAY' after simplification. Two points, though. First, the expression that is the operand of `sizeof' isn't evaluated at all (not in this case, anyhow); all that matters is the expression's type. Second, the compiler is not required to evaluate two equivalent expressions the same way; it's perfectly all right for the compiler to emit different code for `x = 42' and for `x = 40 + 2', or even for `x = 052'. C requires that `sizeof(*ARRAY)' and `sizeof(ARRAY[0])' produce the same type and value, but does not require that they use the same mechanisms to generate the result. > There is amazing difference that depends > on usage of the sizeof operator: > [... sizeof(*BAR) and sizeof(BAR[0]) generate different code ...] > Is there any clear reason of such difference ? None that I can see -- although, as explained above, C does not dictate any particular style of code generation. My wild guess is that since mudflap is concerned with array bounds checking, the difference may arise from the way mudflap adds instrumentation: Perhaps it recognizes one construct as an array- using expression but not the other, and therefore instruments them differently. -- Eric Sosman esosman@comcast-dot-net.invalid |
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?
Eric Sosman <esosman@comcast-dot-net.invalid> writes:
> On 1/9/2013 10:26 AM, m.labanowicz@gmail.com wrote: [...] >> There is amazing difference that depends >> on usage of the sizeof operator: >> [... sizeof(*BAR) and sizeof(BAR[0]) generate different code ...] >> Is there any clear reason of such difference ? > > None that I can see -- although, as explained above, C does > not dictate any particular style of code generation. My wild > guess is that since mudflap is concerned with array bounds > checking, the difference may arise from the way mudflap adds > instrumentation: Perhaps it recognizes one construct as an array- > using expression but not the other, and therefore instruments > them differently. Mudflap probably shouldn't be instrumenting code that's an argument to sizeof in the first place, since it's never executed (barring VLAs). For example, given `int arr[10];` this expression: `sizeof arr[1000]` is perfectly valid, and evaluates to the same value as `sizeof (int)`. "My code is fine, it must be a bug in the development tools" is not the first thought you should have, but in this case it's a distinct possibility. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?
On 1/9/2013 10:26, m.labanowicz@gmail.com wrote:
> > I'm looking for the reason of the MUDFLAP violation > on my 'BIG' C project (no possibility to show), > system: Ubuntu:12.04, gcc:4.6.3. > You don't need to show the big project, but it might help if you showed the violation! Are you linking with libmudflap by using '-lmudflap' with GCC? > NOTE: The same 'BIG' project has been successfully executed > on my old system: Ubuntu:10.04, gcc-(version don't remember). > Mudflap was silent. > > My investigation shows that there > are called some functions before 'main', like: > _GLOBAL__sub_I_00099_0_<org_fun_name> > > Currently MUDFLAP violates before calling 'main' in > _GLOBAL__sub_I_00099_0_<my_function> > > if I change source code of <my_function> > from sizeof(*ARRAY) > to sizeof(ARRAY[0]) > then violation source shifts to another > _GLOBAL__sub_I_00099_0_... function. > That suggests to me the possibility that you are running afoul of undefined behaviour _before_ coming across your 'sizeof' usage, because if you run afoul of undefined behaviour, anything can happen and the precise nature of the weirdness can depend on things that _shouldn't_ make a difference, such as the difference between your two 'sizeof's. > But this algoritm failed in case MUDFLAP violates > at function that has no usage of sizeof(ARRAY) operator. > That's quite possible, since the undefined behaviour might be invoked _before_ the 'sizeof' use. That's the thing about undefined behaviour... While trying to track it down, you might think it's because of "thing #1". (But it's not.) Then you change "thing #1" and find that things change! (But you haven't fixed the undefined behaviour.) But then later it looks like "thing #2" has a problem. > Common for the all functions that MUDFLAP violates is the > static const ARRAY usage, example: > > /*--EXAMPLE-BEG----------------*/ > 01: extern unsigned my_function_check(unsigned a, unsigned b, unsigned c); > 02: void my_function(void) > 03: { > 04: unsigned const SCALE [] = { 0, 1, 2 }; > 05: unsigned const TOSTEP [][2] = { > 06: { 10, 1}, > 07: { 100, 8} > 08: }; > 09: unsigned s = sizeof(SCALE) / sizeof(SCALE[0]); > 10: while (s--) > 11: { > 12: unsigned i = 0; > 13: while (i < (sizeof(TOSTEP) / sizeof(TOSTEP[0]))) > 14: { > 15: unsigned current = 0; > 16: unsigned value = 0; > 17: current = my_function_check(SCALE[s], TOSTEP[i][0], value); > 18: if (current) > 19: { > 20: return; > 21: } > 22: ++i; > 23: } > 24: } > 25: } > /*--EXAMPLE-BEG----------------*/ > > In this example I have not found any reason of > violate before calling the main. > > There is amazing difference that depends > on usage of the sizeof operator: > It's not that amazing, if undefined behaviour is involved. > --[TEST-BEG]------------------------------ > + uname -a > Linux ldrlinux 3.2.0-35-generic-pae #55-Ubuntu SMP Wed Dec 5 18:04:39 UTC 2012 i686 i686 i386 GNU/Linux > + gcc --version > gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 > Copyright (C) 2011 Free Software Foundation, Inc. > This is free software; see the source for copying conditions. There is NO > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. > > + gawk '{printf("%02u: %s\n", NR, $0);}' > + cat bar.c > 01: #include <stddef.h> /* size_t */ > 02: static int const BAR [] = {0,1,2,3,4}; > 03: size_t bar_element_sizeof(void) { > 04: #if ASTERISK > 05: return sizeof(*BAR); > 06: #else > 07: return sizeof(BAR[0]); > 08: #endif > 09: } > + gcc -W -Wall -ansi -pedantic -Werror -fmudflap -DnotASTERISK -c bar.c -o bar_notASTERISK.o > + gcc -W -Wall -ansi -pedantic -Werror -fmudflap -DASTERISK -c bar.c -o bar_ASTERISK.o > + objdump -d bar_notASTERISK.o > + objdump -d bar_ASTERISK.o > + diff bar_notASTERISK.S bar_ASTERISK.S > 2c2 > < bar_notASTERISK.o: file format elf32-i386 > --- >> bar_ASTERISK.o: file format elf32-i386 > 17c17 > < d: 83 ec 08 sub $0x8,%esp > --- >> d: 83 ec 18 sub $0x18,%esp > 19,20c19,28 > < 15: c9 leave > < 16: c3 ret > --- >> 15: c7 44 24 0c 14 00 00 movl $0x14,0xc(%esp) >> 1c: 00 >> 1d: c7 44 24 08 04 00 00 movl $0x4,0x8(%esp) >> 24: 00 >> 25: c7 44 24 04 14 00 00 movl $0x14,0x4(%esp) >> 2c: 00 >> 2d: c7 04 24 00 00 00 00 movl $0x0,(%esp) >> 34: e8 fc ff ff ff call 35 <_GLOBAL__sub_I_00099_0_bar_element_sizeof+0x2b> >> 39: c9 leave >> 3a: c3 ret > --[TEST-EOF]------------------------------ > > Is there any clear reason of such difference ? > Yes. The difference is fully permitted, and even useful. Furthermore, if the undefined behaviour theory is correct, whatever is going wrong is simply accidentally running into this difference, but the _difference_ is not the _cause_ of the undefined behaviour, surely. I'd suggest reviewing _all_ code that is executed _before_ the first mudflap violation. - Shao Miller |
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?
Ok, after long investigation I have successfully prepared simple C program that illustrates the issue:
3 files: - bar.h - bar.c - main.c ------------[TEST-BEG]------------------------- + gawk '{printf("%02u: %s\n", NR, $0);}' bar.h 01: typedef struct 02: { 03: char const * name; 04: int val; 05: } bar_cfg_t; 06: int bar_fun(void); + gawk '{printf("%02u: %s\n", NR, $0);}' bar.c 01: #include "bar.h" 02: #include <stddef.h> /* size_t */ 03: int bar_fun(void) 04: { 05: int result = 0; 06: bar_cfg_t bar_cfg [] = 07: { 08: {"@", 0}, 09: {"#", 0}, 10: {"0", 0}, 11: {"1", 0}, 12: {"2", 0}, 13: {"3", 0}, 14: {"4", 0}, 15: {"5", 0}, 16: #ifdef WORKAROUND_FOR_MUDFLAP 17: {"6", 0}, 18: #endif 19: {"7", 0} 20: }; 21: bar_cfg_t * bc = bar_cfg; 22: size_t i = 0; 23: while (i++ < (sizeof(bar_cfg) / sizeof(bar_cfg[0]))) 24: { 25: bc->val = 123 + (unsigned)(bc->name[0]); 26: result += bc->val; 27: ++bc; 28: } 29: return result; 30: } + gawk '{printf("%02u: %s\n", NR, $0);}' main.c 01: #include <stdio.h> /* printf, size_t */ 02: #include <stdlib.h> /* EXIT_SUCCESS */ 03: #include "bar.h" 04: static int foo_fun(void) 05: { 06: int result = 0; 07: unsigned int const TOSTEP [][2] = 08: { 09: { 100u, 1u}, 10: { 100u, 8u}, 11: { 0x2333445u, 123344u}, 12: { 0x2333445u, 1233446u}, 13: {0x00BFC000u, 0x20000u}, 14: {0x00FFC000u, 0x20000u}, 15: {0x01FFC000u, 0x20000u}, 16: {0x02FFC000u, 0x20000u}, 17: {0x06FFC000u, 0x10000u}, 18: {0x0DFFC000u, 0x10000u} 19: }; 20: size_t i = 0; 21: while (i < (sizeof(TOSTEP) / sizeof(TOSTEP[0]))) 22: { 23: result = TOSTEP[i][0] + TOSTEP[i][1]; 24: i++; 25: } 26: return result; 27: } 28: int main(void) 29: { 30: printf("Hello World !\r\n"); 31: printf("foo_fun = %d\r\n", foo_fun()); 32: printf("bar_fun = %d\r\n", bar_fun()); 33: return EXIT_SUCCESS; 34: } + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c bar.c + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c main.c + gcc -Wl,-Map,a.map main.o bar.o -lmudflap + MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations + ./a.out 01: ******* 02: mudflap violation 1 (register): time=1357813939.099625 ptr=0xbfe56c28 size=72 03: pc=0xb767685e 04: /usr/lib/i386-linux-gnu/libmudflap.so.0(__mf_register+0x3e) [0xb767685e] 05: ./a.out() [0x8048ce0] 06: ./a.out() [0x8048d42] 07: Nearby object 1: checked region begins 8B into and ends 79B into 08: mudflap object 0x8cbf1e8: name=`constant' 09: bounds=[0xbfe56c20,0xbfe56c6f] size=80 area=static check=0r/0w liveness=0 10: alloc time=1357813939.099612 pc=0xb767685e 11: number of nearby objects: 1 12: mf: alloca stack level 0xbfe56b18 13: Hello World ! 14: foo_fun = 234930176 15: bar_fun = 1564 16: ******* 17: mudflap violation 2 (unregister): time=1357813939.100370 ptr=0x8cbfa20 size=0 18: pc=0xb76763d6 19: number of nearby objects: 0 20: number of leaked objects: 0 -----[with: WORKAORUND_FOR_MUDFLAP]------------ + rm -fr bar.o main.o a.map a.out + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -DWORKAROUND_FOR_MUDFLAP=1 -c bar.c + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c main.c + gcc -Wl,-Map,a.map main.o bar.o -lmudflap + MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations + ./a.out 01: mf: harmless duplicate reg 0xbfe45950-0xbfe4599f `constant' 02: mf: alloca stack level 0xbfe45848 03: Hello World ! 04: foo_fun = 234930176 05: bar_fun = 1741 06: number of leaked objects: 0 ------------[TEST-EOF]------------------------- Please note, that after applying additional element to array the issue has gone. So, if this is valid ANSI-C program then this is an issue connected to GCC/MUDFLAP. -- Maciej Labanowicz |
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?
On 1/10/2013 05:40, m.labanowicz@gmail.com wrote:
> Ok, after long investigation I have successfully prepared simple C program that illustrates the issue: > 3 files: > - bar.h > - bar.c > - main.c > > ------------[TEST-BEG]------------------------- > + gawk '{printf("%02u: %s\n", NR, $0);}' bar.h > 01: typedef struct > 02: { > 03: char const * name; > 04: int val; > 05: } bar_cfg_t; > 06: int bar_fun(void); Maybe add a helper macro in here: #if USE_ASTERISK # define Countof(array) (sizeof (array) / sizeof *(array)) #else # define Countof(array) (sizeof (array) / sizeof (array)[0]) #endif > + gawk '{printf("%02u: %s\n", NR, $0);}' bar.c > 01: #include "bar.h" > 02: #include <stddef.h> /* size_t */ > 03: int bar_fun(void) > 04: { > 05: int result = 0; > 06: bar_cfg_t bar_cfg [] = > 07: { > 08: {"@", 0}, > 09: {"#", 0}, > 10: {"0", 0}, > 11: {"1", 0}, > 12: {"2", 0}, > 13: {"3", 0}, > 14: {"4", 0}, > 15: {"5", 0}, > 16: #ifdef WORKAROUND_FOR_MUDFLAP > 17: {"6", 0}, > 18: #endif > 19: {"7", 0} > 20: }; > 21: bar_cfg_t * bc = bar_cfg; > 22: size_t i = 0; > 23: while (i++ < (sizeof(bar_cfg) / sizeof(bar_cfg[0]))) > 24: { > 25: bc->val = 123 + (unsigned)(bc->name[0]); > 26: result += bc->val; > 27: ++bc; > 28: } > 29: return result; > 30: } Note that 'i' is being used for iteration over 'bar_cfg', but by line 29, its index is _two_past_ the array. That's worth a bounds-checking diagnostic, would you agree? I don't know why you're not using a 'for' loop: /* Circa line 22 */ size_t i; for (i = 0; i < Countof(bar_cfg); ++i) { bc->val = 123 + (unsigned)(bc->name[0]); result += bc->val; ++bc; } return result; } > + gawk '{printf("%02u: %s\n", NR, $0);}' main.c > 01: #include <stdio.h> /* printf, size_t */ > 02: #include <stdlib.h> /* EXIT_SUCCESS */ > 03: #include "bar.h" > 04: static int foo_fun(void) > 05: { > 06: int result = 0; > 07: unsigned int const TOSTEP [][2] = > 08: { > 09: { 100u, 1u}, > 10: { 100u, 8u}, > 11: { 0x2333445u, 123344u}, > 12: { 0x2333445u, 1233446u}, > 13: {0x00BFC000u, 0x20000u}, > 14: {0x00FFC000u, 0x20000u}, > 15: {0x01FFC000u, 0x20000u}, > 16: {0x02FFC000u, 0x20000u}, > 17: {0x06FFC000u, 0x10000u}, > 18: {0x0DFFC000u, 0x10000u} > 19: }; > 20: size_t i = 0; > 21: while (i < (sizeof(TOSTEP) / sizeof(TOSTEP[0]))) > 22: { > 23: result = TOSTEP[i][0] + TOSTEP[i][1]; > 24: i++; > 25: } > 26: return result; /* Circa line 20 */ size_t i; for (i = 0; i < Countof(TOSTEP); ++i) result = TOSTEP[i][0] + TOSTEP[i][1]; return result; > 27: } > 28: int main(void) > 29: { > 30: printf("Hello World !\r\n"); > 31: printf("foo_fun = %d\r\n", foo_fun()); > 32: printf("bar_fun = %d\r\n", bar_fun()); > 33: return EXIT_SUCCESS; > 34: } > + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c bar.c > + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c main.c > + gcc -Wl,-Map,a.map main.o bar.o -lmudflap > + MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations > + ./a.out > 01: ******* > 02: mudflap violation 1 (register): time=1357813939.099625 ptr=0xbfe56c28 size=72 > 03: pc=0xb767685e > 04: /usr/lib/i386-linux-gnu/libmudflap.so.0(__mf_register+0x3e) [0xb767685e] > 05: ./a.out() [0x8048ce0] > 06: ./a.out() [0x8048d42] > 07: Nearby object 1: checked region begins 8B into and ends 79B into > 08: mudflap object 0x8cbf1e8: name=`constant' > 09: bounds=[0xbfe56c20,0xbfe56c6f] size=80 area=static check=0r/0w liveness=0 > 10: alloc time=1357813939.099612 pc=0xb767685e > 11: number of nearby objects: 1 > 12: mf: alloca stack level 0xbfe56b18 > 13: Hello World ! > 14: foo_fun = 234930176 > 15: bar_fun = 1564 > 16: ******* > 17: mudflap violation 2 (unregister): time=1357813939.100370 ptr=0x8cbfa20 size=0 > 18: pc=0xb76763d6 > 19: number of nearby objects: 0 > 20: number of leaked objects: 0 > -----[with: WORKAORUND_FOR_MUDFLAP]------------ > + rm -fr bar.o main.o a.map a.out > + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -DWORKAROUND_FOR_MUDFLAP=1 -c bar.c > + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c main.c > + gcc -Wl,-Map,a.map main.o bar.o -lmudflap > + MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations > + ./a.out > 01: mf: harmless duplicate reg 0xbfe45950-0xbfe4599f `constant' > 02: mf: alloca stack level 0xbfe45848 > 03: Hello World ! > 04: foo_fun = 234930176 > 05: bar_fun = 1741 > 06: number of leaked objects: 0 > ------------[TEST-EOF]------------------------- > > Please note, that after applying additional element to array > the issue has gone. > > So, if this is valid ANSI-C program then this > is an issue connected to GCC/MUDFLAP. > MUDFLAP can diagnose stuff that's permitted by C90, such as warning you that an index used for iteration has gone too far. Usually you want to index one-past an array, at most. Do the 'for' loops have any problems? - Shao Miller |
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?
On 1/10/2013 08:31, Shao Miller wrote:
> On 1/10/2013 05:40, m.labanowicz@gmail.com wrote: >> 21: bar_cfg_t * bc = bar_cfg; >> 22: size_t i = 0; >> 23: while (i++ < (sizeof(bar_cfg) / sizeof(bar_cfg[0]))) >> 24: { >> 25: bc->val = 123 + (unsigned)(bc->name[0]); >> 26: result += bc->val; >> 27: ++bc; >> 28: } >> 29: return result; >> 30: } > > Note that 'i' is being used for iteration over 'bar_cfg', but by line > 29, its index is _two_past_ the array. That's worth a bounds-checking > diagnostic, would you agree? > > I don't know why you're not using a 'for' loop: > > /* Circa line 22 */ > size_t i; > > for (i = 0; i < Countof(bar_cfg); ++i) > { > bc->val = 123 + (unsigned)(bc->name[0]); > result += bc->val; > ++bc; > } > return result; > } > There is another "problem" here, and that's that you are indexing into the array with two difference indices. I'd suggest either: /* Circa line 21 */ size_t i; for (i = 0; i < Countof(bar_cfg); ++i) { bar_cfg[i]->val = 123 + (unsigned)(bar_cfg[i]->name[0]); result += bar_cfg[i]->val; } return result; } Or: /* Circa line 21 */ bar_cfg_t * const end = bar_cfg + Countof(bar_cfg); bar_cfg_t * bc; for (bc = bar_cfg; bc < end; ++bc) { bc->val = 123 + (unsigned)(bc->name[0]); result += bc->val; } return result; } (By the way, I like your spaces surrounding your asterisk in the pointer declaration. :) ) - Shao Miller |
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?
m.labanowicz@gmail.com writes:
> Ok, after long investigation I have successfully prepared simple C > program that illustrates the issue: > 3 files: > - bar.h > - bar.c > - main.c A data point: your example compiles and runs clean with gcc 4.7.2 and mudflap 4.7. <snip> -- Ben. |
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?
Code without loops, issue is still present:
---------------------------------------------- + uname -a Linux ldrlinux 3.2.0-35-generic-pae #55-Ubuntu SMP Wed Dec 5 18:04:39 UTC 2012 i686 i686 i386 GNU/Linux + gcc --version gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 Copyright (C) 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + gawk '{printf("%02u: %s\n", NR, $0);}' bar.h 01: int bar_fun(unsigned idx); 02: #define ARRAY_NO_OF_ELEMENTS(a) ((unsigned)(sizeof(a) / sizeof(*a))) + gawk '{printf("%02u: %s\n", NR, $0);}' bar.c 01: #include "bar.h" 02: int bar_fun(unsigned idx) 03: { 04: int bar_cfg [][2] = 05: { 06: {9, 0}, 07: {8, 1}, 08: {7, 2}, 09: {6, 3}, 10: {5, 4}, 11: {4, 5}, 12: {3, 6}, 13: {2, 7}, 14: #ifdef WORKAROUND_FOR_MUDFLAP 15: {1, 8}, 16: #endif 17: {0, 9} 18: }; 19: return (idx < ARRAY_NO_OF_ELEMENTS(bar_cfg)) ? bar_cfg[idx][1] : -1; 20: } + gawk '{printf("%02u: %s\n", NR, $0);}' main.c 01: #include <stdio.h> /* printf */ 02: #include <stdlib.h> /* EXIT_SUCCESS */ 03: #include "bar.h" 04: static int foo_fun(unsigned idx) 05: { 06: int const TOSTEP [][2] = 07: { 08: {0, 9}, 09: {1, 8}, 10: {2, 7}, 11: {3, 6}, 12: {4, 5}, 13: {5, 4}, 14: {6, 3}, 15: {7, 2}, 16: {8, 1}, 17: {9, 0} 18: }; 19: return (idx < ARRAY_NO_OF_ELEMENTS(TOSTEP)) ? TOSTEP[idx][1] : -1; 20: } 21: int main(void) 22: { 23: printf("Hello World !\r\n"); 24: printf("foo_fun = %d\r\n", foo_fun(4)); 25: printf("bar_fun = %d\r\n", bar_fun(4)); 26: return EXIT_SUCCESS; 27: } + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c bar.c + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c main.c + gcc -Wl,-Map,a.map main.o bar.o -lmudflap + MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations + ./a.out + gawk '{printf("%02u: %s\n", NR, $0);}' 01: ******* 02: mudflap violation 1 (register): time=1357829219.568594 ptr=0xbfd9f6b8 size=72 03: pc=0xb762b85e 04: /usr/lib/i386-linux-gnu/libmudflap.so.0(__mf_register+0x3e) [0xb762b85e] 05: ./a.out() [0x8048979] 06: ./a.out() [0x80489e2] 07: Nearby object 1: checked region begins 8B into and ends 79B into 08: mudflap object 0x9a021e8: name=`constant' 09: bounds=[0xbfd9f6b0,0xbfd9f6ff] size=80 area=static check=0r/0w liveness=0 10: alloc time=1357829219.568588 pc=0xb762b85e 11: number of nearby objects: 1 12: mf: alloca stack level 0xbfd9f5a8 13: Hello World ! 14: foo_fun = 5 15: bar_fun = 4 16: ******* 17: mudflap violation 2 (unregister): time=1357829219.569060 ptr=0x9a02678 size=0 18: pc=0xb762b3d6 19: number of nearby objects: 0 20: number of leaked objects: 0 ------------[with: WORKAROUND_FOR_MUDFLAP]-------------------- + rm -fr bar.o main.o a.map a.out + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -DWORKAROUND_FOR_MUDFLAP=1 -c bar.c + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c main.c + gcc -Wl,-Map,a.map main.o bar.o -lmudflap + MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations + ./a.out + gawk '{printf("%02u: %s\n", NR, $0);}' 01: mf: harmless duplicate reg 0xbfbc1c50-0xbfbc1c9f `constant' 02: mf: alloca stack level 0xbfbc1b48 03: Hello World ! 04: foo_fun = 5 05: bar_fun = 4 06: number of leaked objects: 0 ---------------------------------------------- Usage of sizeof(ARRAY[0]) or sizeof(*ARRAY) has no impact to the result, issue is present. Best Regards -- Maciej Labanowicz |
| All times are GMT. The time now is 06:12 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.