And for fun, try the quiz at http://blog.regehr.org/archives/721. Then cry as 
you realize how much broken code there must be out there...

> -----Original Message-----
> From: Michiel Konstapel [mailto:m.konsta...@sownet.nl]
> Sent: Friday, February 15, 2013 09:31
> To: Rick Kimball; mspgcc-users@lists.sourceforge.net
> Subject: Re: [Mspgcc-users] msp430-gcc 4.6.3 optimizer killing my code
> 
> Signed overflow is actually undefined behaviour in C/C++, and the
> compiler is free to do whatever it wants in that case. For gcc, there's
> a flag to make signed integer arithmetic wrap around, though:
> 
>       -fwrapv
>       This option instructs the compiler to assume that signed
> arithmetic overflow of
>       addition, subtraction and multiplication wraps around using twos-
> complement
>       representation. This flag enables some optimizations and disables
> others.
> 
> It's one of the "safety switches" I've enabled for our embedded code,
> because it's something many people (including myself until recently)
> don't know about. Especially if you're coming from Java, where signed
> overflow *is* defined to wrap.
> 
> John Regehr has a large amount of interesting, if scary, information
> about undefined behaviour in C on his blog, for example
> http://blog.regehr.org/archives/759 and
> http://blog.regehr.org/archives/761.
> 
> HTH,
> Michiel
> 
> > -----Original Message-----
> > From: Rick Kimball [mailto:rick.kimb...@gmail.com]
> > Sent: Friday, February 15, 2013 03:19
> > To: mspgcc-users@lists.sourceforge.net
> > Subject: [Mspgcc-users] msp430-gcc 4.6.3 optimizer killing my code
> >
> > I've been working on some C++ template based classes and ran into a
> > snag. At first I thought it was related to the C++ templates however
> > it turns out when I reduced the code down to a straight 'C'
> > implementation I still have the same problem.
> >
> > The code below has issues with the int8_t data type. In "test 2" i8
> > starts at 126 and incrementing it should make it roll over to a
> > negative number but it doesn't. This problem appears when i use -Os (
> > which is my normal mode of operation ) and does go away if I back off
> > and use -O1. If nothing else it would interesting if others try this
> > with their version of the compiler. I'm using the linux version that
> > ships with Energia:
> > gcc version 4.6.3 20120301 (mspgcc LTS 20120406 unpatched) (MSPGCC
> > 20120406 (With patches: sf3540953 sf3559978)) Adding volatile to just
> > the int8_t declaration will get rid of the problem.
> >
> > If you use msp430-gcc you might try this code and post your results.
> >
> > Secondary question, red-hat has been churning away with the msp430-
> gcc
> > code for a while. Is there an ETA for when we might see a new version
> > from them?
> >
> > Thanks,
> >
> > -rick
> >
> > code on github: https://gist.github.com/RickKimball/4957969
> >
> > /**
> >  * signedtest.c - this fails to output int8_t values properly when
> > optimized with -Os
> >  *
> >  * Compiled like this:
> >  *
> >  * $ msp430-gcc -mmcu=msp430g2553 -DF_CPU=16000000 -Os -Wall \
> >  *   -Wno-main -g -mdisable-watchdog -fdata-sections -ffunction-
> > sections \
> >  *   -Wl,--gc-sections signedtest.c
> >  *
> >  * $ mspdebug rf2500 "prog a.out"
> >  *
> >  * compiling with -O1 produces proper output, as does changing the
> >  * int8_t to volatile int8_t
> >  *
> >  */
> >
> > #include <msp430.h>
> > #include <stdint.h>
> > #include <stdlib.h>
> >
> > /**
> >  * serial output routines
> >  */
> > void printc(const char c) {
> >     while(!(IFG2 & UCA0TXIFG));
> >     IFG2 &= ~UCA0TXIFG;
> >     UCA0TXBUF = c;
> > }
> >
> > void prints(const char *s) {
> >     while(*s)
> >       printc(*s++);
> > }
> >
> > void printi(int8_t i) {
> >   char buff[8];
> >
> > #if 1
> >   if ( i < 0 ) {
> >     printc('-');
> >     i=-i;
> >   }
> >   utoa((i & 0xff),buff,10);
> > #else
> >   itoa((int8_t)i,buff,10); /* also tried this, also failed */
> > #endif
> >
> >   prints(buff);
> > }
> >
> > void printu(uint8_t i) {
> >   char buff[8];
> >
> >   utoa((i & 0xff),buff,10);
> >   prints(buff);
> > }
> >
> > void println() {
> >   printc('\n');
> > }
> >
> > static const uint32_t brd = (F_CPU + (9600 >> 1)) / 9600; // Bit rate
> > divisor
> >
> > int main(void) {
> >   uint16_t indx;
> >
> > #define BAD
> >
> > #if defined(GOOD)
> >   volatile int8_t i8; // test2 produces valid results
> > #elif defined(BAD)
> >   int8_t i8; // broken for test2 unless marked volatile or you use -
> O1
> > #endif
> >   uint8_t u8;
> >
> >   WDTCTL = WDTPW + WDTHOLD;                       // No watchdog
> reset
> >                                                   //
> >   DCOCTL = 0;                                     // Run at 16 MHz
> >   BCSCTL1 = CALBC1_16MHZ;                         //
> >   DCOCTL  = CALDCO_16MHZ;                         //
> >
> >   //P1DIR |= BIT0 | BIT4; P1SEL |= BIT4;
> >
> >   // GPIO Configuration  ;                        // Set alternate
> > function I/O for UART & SPI
> >   P1SEL  |= BIT2;                                 // UART P1.2(tx)
> >   P1SEL2 |= BIT2;
> >
> >   // Serial Config
> >   UCA0CTL1 = UCSWRST;                             // Hold USCI in
> > reset to allow configuration
> >   UCA0CTL0 = 0;                                   // No parity, LSB
> > first, 8 bits, one stop bit, UART (async)
> >   UCA0BR1 = (brd >> 12) & 0xFF;                   // High byte of
> whole
> > divisor
> >   UCA0BR0 = (brd >> 4) & 0xFF;                    // Low byte of
> whole
> > divisor
> >   UCA0MCTL = ((brd << 4) & 0xF0) | UCOS16;        // Fractional
> > divisor, oversampling mode
> >   UCA0CTL1 = UCSSEL_2;                            // Use SMCLK for
> bit
> > rate generator, release reset
> >
> >
> >   prints("-test 1- int8_t=125, uint8_t=125 - signed/unsigned boundary
> > rollover\n RESULTS: always succeeds\n");
> >   i8=125; u8=125;
> >   for(indx=0; indx < 5; indx++, i8++, u8++) {
> >     printi(i8);
> >     prints(", ");
> >     printu(u8);
> >     println();
> >   }
> >
> >   prints("-test 2- int8_t=126, uint8_t=126 - signed/unsigned boundary
> > rollover\n RESULTS: fails unless volatile\n");
> >   i8=126; u8=126;
> >   for(indx=0; indx < 4; indx++, i8++, u8++) {
> >     printi(i8);
> >     prints(", ");
> >     printu(u8);
> >     println();
> >   }
> >
> >   prints("-test 3- int8_t=127, uint8_t=127 - signed/unsigned boundary
> > rollover\n RESULTS: always ok\n");
> >   i8=127; u8=127;
> >   for(indx=0; indx < 3; indx++, i8++, u8++) {
> >     printi(i8);
> >     prints(", ");
> >     printu(u8);
> >     println();
> >   }
> >
> >   while(1);
> > }
> >
> > #if 0
> > >>> Bad results when int8_t not volatile
> >
> >    -test 1- int8_t=125, uint8_t=125 - signed/unsigned boundary
> rollover
> >     RESULTS: always succeeds
> >    125, 125
> >    126, 126
> >    127, 127
> >    -128, 128
> >    -127, 129
> >    -test 2- int8_t=126, uint8_t=126 - signed/unsigned boundary
> rollover
> >     RESULTS: fails unless volatile
> >    126, 126
> >    127, 127
> >    127, 128 << fail this is the wrong result
> >    127, 129 << fail this is the wrong result
> >    -test 3- int8_t=127, uint8_t=127 - signed/unsigned boundary
> rollover
> >     RESULTS: always ok
> >    127, 127
> >    -128, 128
> >    -127, 129
> >
> >
> > >>> Good results when using volatile int8_t
> >
> >   -test 1- int8_t=125, uint8_t=125 - signed/unsigned boundary
> rollover
> >    RESULTS: always succeeds
> >   125, 125
> >   126, 126
> >   127, 127
> >   -128, 128
> >   -127, 129
> >   -test 2- int8_t=126, uint8_t=126 - signed/unsigned boundary
> rollover
> >    RESULTS: fails unless volatile
> >   126, 126
> >   127, 127
> >   -128, 128
> >   -127, 129
> >   -test 3- int8_t=127, uint8_t=127 - signed/unsigned boundary
> rollover
> >    RESULTS: always ok
> >   127, 127
> >   -128, 128
> >   -127, 129
> >
> >
> > #endif
> >
> > ---------------------------------------------------------------------
> --
> > -------
> > Free Next-Gen Firewall Hardware Offer
> > Buy your Sophos next-gen firewall before the end March 2013
> > and get the hardware for free! Learn more.
> > http://p.sf.net/sfu/sophos-d2d-feb
> > _______________________________________________
> > Mspgcc-users mailing list
> > Mspgcc-users@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/mspgcc-users
> 
> -----------------------------------------------------------------------
> -------
> Free Next-Gen Firewall Hardware Offer
> Buy your Sophos next-gen firewall before the end March 2013
> and get the hardware for free! Learn more.
> http://p.sf.net/sfu/sophos-d2d-feb
> _______________________________________________
> Mspgcc-users mailing list
> Mspgcc-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mspgcc-users

------------------------------------------------------------------------------
Free Next-Gen Firewall Hardware Offer
Buy your Sophos next-gen firewall before the end March 2013 
and get the hardware for free! Learn more.
http://p.sf.net/sfu/sophos-d2d-feb
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users

Reply via email to