On Monday 01 October 2007 09:48:23 am Eric Weddington wrote: > Its an interesting question. I'm not sure what the answer is. Perhaps a > language lawyer on comp.lang.c could explain the reasoning behind the > current standard.
http://thread.gmane.org/gmane.linux.kernel/523210 for the Linux view on Volatile. The links in the code below are worth following. What follows is John Regehr's Volatile test case, from the Cyclone Compiler list, see: http://www.nabble.com/volatile-tf4417773.html "In case anyone's interested I'm attaching my test program. The functions at the top of the file must compile to one load from x followed by one store to x. Thanks, John Regehr" /* add: load and store conditional on constant, variable, etc. more temptation for loop hoisting short-circuit tests possibility: generate all expressions of size <=N that result in an lvalue pointing to x and/or and rvalue evaluating to x also glue code into larger functions (or use inlining) type multiple data widths, signed and unsigned, const volatile might as well also test nonvolatile types... goal: break gcc and Intel compilers! ask who about this? cyclone people, c0x people, ... volatile: structs, unions, arrays, ... http://vstte.ethz.ch/pdfs/vstte-rushby-position.pdf http://mir.cs.uiuc.edu/~marinov/publications/Marinov04TestingStructurallyComplexInputs.pdf http://www.csl.sri.com/~rushby/papers/vstte07.ps.gz - look up wording of volatile in C89, C99, C0x - automate testing using an interpreter: look for loads and stores, this would allow systematic testing of option and program variants - http://www.nullstone.com/htmls/category/volatile.htm test: more gccs Realview ARM compiler Codewarrior for HC11 LLVM LCC MSVC++ IAR compilers win-avr win-arm msp430-gcc */ //////////////////////////////////////////////////////////////////////// // typedef unsigned int t; typedef int t; volatile t x; void self_assign_1 (void) { x = x; } void self_assign_2 (void) { t sink = x; x = sink; } void self_assign_3 (void) { volatile t *xp = &x; *xp = *xp; } void self_assign_4 (void) { volatile t *xp = &x; t sink = *xp; *xp = sink; } void self_assign_5 (void) { volatile t *xp1 = &x; volatile t *xp2 = &x; *xp1 = *xp2; } void self_assign_6 (void) { volatile t *xp = &x; volatile t **xpp = &xp; t sink = **xpp; **xpp = sink; } void self_assign_7 (void) { volatile t *xp1 = &x; volatile t *xp2 = &x; volatile t **xpp1 = &xp1; volatile t **xpp2 = &xp2; **xpp1 = **xpp2; } void self_assign_8 (void) { volatile t *xp = &x; volatile t **xpp = &xp; t sink = *xp; **xpp = sink; } void self_assign_9 (void) { volatile t *xp1 = &x; volatile t *xp2 = &x; volatile t **xpp2 = &xp2; *xp1 = **xpp2; } void self_assign_10 (void) { volatile t *xp = &x; volatile t **xpp = &xp; t sink = **xpp; *xp = sink; } void self_assign_11 (void) { volatile t *xp1 = &x; volatile t *xp2 = &x; volatile t **xpp1 = &xp1; **xpp1 = *xp2; } void or_1 (void) { x |= 0; } void or_2 (void) { x = x | 0; } void or_3 (void) { t sink = x | 0; x = sink; } void or_4 (void) { t zero = 0; t sink = x | zero; x = sink; } void or_5 (void) { volatile t zero = 0; t sink = x | zero; x = sink; } void or_6 (void) { t zero = 0; volatile t sink = x | zero; x = sink; } void and_1 (void) { x &= ~0; } void and_2 (void) { x = x & ~0; } void and_3 (void) { t sink = x & ~0; x = sink; } void and_4 (void) { t not_zero = ~0; t sink = x & not_zero; x = sink; } void and_5 (void) { volatile t not_zero = ~0; t sink = x & not_zero; x = sink; } void and_6 (void) { t not_zero = ~0; volatile t sink = x & not_zero; x = sink; } volatile t y; void loop_1 (void) { t i; t result = y; for (i=0; i<10; i++) { result += x; } y = result; } void loop_2 (void) { t i; for (i=0; i<10; i++) { x += 3; } } void loop_3 (void) { t i; volatile t z; for (i=0; i<10; i++) { z += 3; } } void loop_4 (t n) { t b; t res = 0; for (b=0; b<n; b++) { res += x; } } void loop_5 (t n) { t b; t res = n; for (b=0; b<n; b++) { x += res; } } void load_only_1 (void) { x; } void load_only_2 (void) { 1 && x; } void load_only_3 (void) { 1 && x && 0; } void load_only_4 (void) { 1 && x && 0 && x; } void load_only_5 (void) { 0 || x; } void load_only_6 (void) { 0 || x || 1; } void load_only_7 (void) { 0 || x || 1 || x; } int my_true = 1; int my_false = 0; void load_only_8 (void) { my_true && x; } void load_only_9 (void) { my_true && x && my_false; } void load_only_10 (void) { my_true && x && my_false && x; } void load_only_11 (void) { my_false || x; } void load_only_12 (void) { my_false || x || my_true; } void load_only_13 (void) { my_false || x || my_true || x; } volatile int vol_my_true = 1; volatile int vol_my_false = 0; void load_only_14 (void) { vol_my_true && x; } void load_only_15 (void) { vol_my_true && x && vol_my_false; } void load_only_16 (void) { vol_my_true && x && vol_my_false && x; } void load_only_17 (void) { vol_my_false || x; } void load_only_18 (void) { vol_my_false || x || vol_my_true; } void load_only_19 (void) { vol_my_false || x || vol_my_true || x; } //////////////////////////////////////////////////////////////////////// -- http://www.wearablesmartsensors.com/ http://www.softwaresafety.net/ http://www.designer-iii.com/ http://www.unusualresearch.com/ _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list