From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31684 invoked by alias); 9 Oct 2013 15:40:07 -0000 Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org Received: (qmail 31668 invoked by uid 89); 9 Oct 2013 15:40:06 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.3.2 X-HELO: jhsvmret01.hatteland.com Received: from jhsvmret01.hatteland.com (HELO jhsvmret01.hatteland.com) (213.162.247.110) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Wed, 09 Oct 2013 15:40:05 +0000 Received: from JHSVMHUB01.netsentral.no (172.21.1.101) by jhsvmret01.hatteland.com (213.162.247.110) with Microsoft SMTP Server (TLS) id 14.2.318.4; Wed, 9 Oct 2013 17:40:02 +0200 Received: from [192.168.0.65] (172.21.20.11) by e2010.hatteland.com (172.21.1.25) with Microsoft SMTP Server (TLS) id 14.2.318.4; Wed, 9 Oct 2013 17:40:00 +0200 Message-ID: <525578D0.1040904@westcontrol.com> Date: Wed, 09 Oct 2013 15:40:00 -0000 From: David Brown User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130806 Thunderbird/17.0.8 MIME-Version: 1.0 To: vijay nag CC: Jonathan Wakely , "gcc-help@gcc.gnu.org" Subject: Re: Crazy compiler optimization References: In-Reply-To: Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7bit X-SW-Source: 2013-10/txt/msg00014.txt.bz2 On 09/10/13 12:02, vijay nag wrote: > On Wed, Oct 9, 2013 at 3:24 PM, Jonathan Wakely wrote: >> On 9 October 2013 10:36, vijay nag wrote: >>> Hello GCC, >>> >>> I'm facing a wierd compiler optimization problem. Consider the code >>> snippet below >>> >>> #include >>> >>> int printChar(unsigned long cur_col, unsigned char c) >>> { >>> char buf[256]; >>> char* bufp = buf; >>> char cnt = sizeof(buf) - 2; /* overflow in implicit type conversion */ >>> unsigned long terminal_width = 500; >>> >>> while ((cur_col++ < terminal_width) && cnt) { >>> *bufp++ = c; >>> cnt--; >>> } >> >> >>> Basically the crash here is because of elimination of the check in the >>> if-clause "&& cnt" which is causing stack overrun and thereby SIGSEGV. >>> While standards may say that the behaviour is >>> undefined when an unsigned value is stored in a signed value, >> >> Standards do not say that. 254 cannot be presented in a char if char >> is a signed type, so it's an overflow, which is undefined behaviour. >> Storing an unsigned value that doesn't overflow is OK. >> >>> can a >>> language lawyer explain to me why GCC chose to eliminate code >>> pertaining to cnt considering it as dead-code ? >> >> cnt is initialized to -2 (after an overflow) and then you decrement it >> so it gets more negative. The "&& cnt" condition will never be false, >> because cnt starts non-zero and gets further from zero, so will never >> reach zero. > > Alright that is perfectly valid behaviour. Why does compiler consider > it to be a unsigned type at optimization level zero ? i.e. I see a > wrap around after > -128 to 128 ? > Without optimisation, the compiler generates simpler code without trying to save time and space. Thus it actually generates code to do the tests and the decrement operation, rather than spending the effort "thinking" about whether or not they are necessary. It turns out that on your system (and almost all modern systems), the simplistic machine code thus generated has the effect you were looking for. It's easy to correct the code by picking a more appropriate type for "cnt". Incidentally, you should never assume that plain "char" is signed or unsigned. It varies between platforms, and can be changed by compiler flags. If you mean an "signed char", call it "signed char". Far better, of course, is to use and call it "int8_t" or "uint8_t" as appropriate, if you really want an 8-bit integer.