From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 55412 invoked by alias); 6 Feb 2018 15:03:11 -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 55392 invoked by uid 89); 6 Feb 2018 15:03:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=PROMOTION, xy, jvm, ptb X-HELO: mail-wm0-f47.google.com Received: from mail-wm0-f47.google.com (HELO mail-wm0-f47.google.com) (74.125.82.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 06 Feb 2018 15:03:07 +0000 Received: by mail-wm0-f47.google.com with SMTP id t74so4357815wme.3 for ; Tue, 06 Feb 2018 07:03:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:date:to:subject:message-id:reply-to :mime-version:content-transfer-encoding; bh=uiinOFHdEUe+xH4DDuSzJF7BTZrSKAnNq1f0bPyOasg=; b=H9UMpJ2wHHJQ36PfzLjDOvUqSVWmhtbauXYrTQqQkixLnUTRrVJ+hjAK0OejJ2Uvnu ma4nxZMNBzazaauzC1PXbhpw4oQEcOkDjrEHVgNfu3mxUscMJrx7E7mZMvX5SO7k7KXj BCbUKqm7raURsqf3bT8Du2zOfuooM9XsBAVu6q3spzsa8bALnGt5HvyZKyftGa+Qnasv hkoGsxrMptk4qqcegCNANb6RupoekqoclFOYAs+rmkVIzYZpbGnQYedWeM2knoEKWIhl ACYvMWqgnCoBmQW51omDWybv5GEQv8tsc2W/jdc4+2gZNCudViYOyHYeIc8gdb+Gf1/N zbyQ== X-Gm-Message-State: APf1xPBu/VPjgjR2z+xz9V5kjEW4mKGlpQ4wxGeaihIYTD5PEF5G9WI5 0giqG3hsv3VjoWB9Ww3pYDxMHQ== X-Google-Smtp-Source: AH8x227zNZ5qao68wlooKvvX+8of7w0x4402PxuAWB8vVOpBRX3I1OB1X3UrDKMsJW54ZmHuGbpaAw== X-Received: by 10.28.140.9 with SMTP id o9mr2144129wmd.28.1517929385421; Tue, 06 Feb 2018 07:03:05 -0800 (PST) Received: from betty.enbd.org ([80.251.191.198]) by smtp.gmail.com with ESMTPSA id w50sm7287640wrb.33.2018.02.06.07.03.04 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 07:03:05 -0800 (PST) From: Peter Breuer X-Google-Original-From: Peter Breuer Date: Tue, 06 Feb 2018 15:03:00 -0000 To: gcc-help@gcc.gnu.org Subject: signed/unsigned integer conversion for right shift seems against C99 rule Message-ID: <20180206150300.457d70e5@betty.enbd.org> Reply-To: Peter.T.Breuer@gmail.com MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-SW-Source: 2018-02/txt/msg00017.txt.bz2 int main() { signed int x = 0x80000005u; unsigned int y = 0x00000002u; signed int z = x >> y; printf("0x%0x\n", z); return 0; } % gcc -std=c99 test.c test.c: In function 'main': test.c:6:3: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration] printf("0x%0x\n", z); ^ test.c:6:3: warning: incompatible implicit declaration of built-in function 'printf' (I'll live with that warning - just for the purpose of a clean example!) % ./a.out 0xe0000001 ^ SIGNED right shift OK, so x>>y was done signed. That means both x,y were converted to signed int (trivially). However, that seems against C99 rules, which seem to say one should convert to unsigned int in mixed sign equal rank situations. First: NO INTEGER PROMOTION is done, by this rule any operand whose type ranks lower than int is automatically converted to the type int, provided int is capable of representing all values of the operand's original type. If int is not sufficient, the operand is converted to unsigned int. Both x and y are int, so do not rank "lower than int". Rule does not apply. All as is. So INTEGER CONVERSION applies from there: If both operands are integers, integer promotion is first performed on both operands. If after integer promotion the operands still have different types, conversion continues as follows: They still have "different types", one being signed int and the other being unsigned it. So CONVERSION happens: If one operand has an unsigned type T whose conversion rank is at least as high as that of the other operand's type, then the other operand is converted to type T. We're there. Both are rank "int" so "at least as high" applies. One (y) has an unsigned type T="unsigned int", so the other (x) must be converted to T="unsigned int". Then the operation gets done as unsigned int >> unsigned int Except it doesn't. The sign bit on the LHS was extended as the printf showed with its "0xe..." at the front, so a shift-right-arithmetic got done, not a shift-right-logical. If you wonder if a SRL is available at all, it is. Declaring both x and y as unsigned int (i.e., change decl of x only to unsigned int) gives the expected SRL output. % ./a.out 0x20000001 ^ zero-extended from 0x8..., not sign-extended. That's a SRL, not a SRA. What am I reading wrong in the standards? (which are nigh on incomprehensible - what does "can be represented as" mean? One can't represent negative numbers in the unsigned version of the same type ever, and one can't represent large positive numbers in the signed version of the type ever, so one can never get "can be represented as"). Is this intended? Well-known to everyone but me? % gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/i586-linux-gnu/4.9/lto-wrapper Target: i586-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.9.2-10' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-i386/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-i386 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-i386 --with-arch-directory=i386 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-targets=all --enable-multiarch --with-arch-32=i586 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=i586-linux-gnu --host=i586-linux-gnu --target=i586-linux-gnu Thread model: posix gcc version 4.9.2 (Debian 4.9.2-10) The gcc notes at https://gcc.gnu.org/c99status.html seem to say integer constant type rules GCC 3.3 integer promotion rules GCC 4.0 and nothing else. Where is current information on standards compliance? The manual says c99 c9x iso9899:1999 iso9899:199x ISO C99. Note that this standard is not yet fully supported; ^^^^^^^^^^^^^^^^^^^^^^^^ see for more information. The names c9x and iso9899:199x are deprecated. Any info that would deconfuse me? Regards to any language lawyers who pass by on the other side or this side. PTB