From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43289) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WOUna-0002cA-3e for qemu-devel@nongnu.org; Fri, 14 Mar 2014 12:17:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WOUnU-0000Fp-4i for qemu-devel@nongnu.org; Fri, 14 Mar 2014 12:17:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:23182) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WOUnT-0000Fl-Sw for qemu-devel@nongnu.org; Fri, 14 Mar 2014 12:17:24 -0400 Message-ID: <53232B90.5060408@redhat.com> Date: Fri, 14 Mar 2014 17:17:20 +0100 From: Laszlo Ersek MIME-Version: 1.0 References: <3096076082478dafe78553ab5cbd8b572904cbc4.1394794127.git.jcody@redhat.com> <20140314153639.GD1985@redhat.com> In-Reply-To: <20140314153639.GD1985@redhat.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH] block: Explicitly specify 'unsigned long long' for VHDX 64-bit constants List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Richard W.M. Jones" , Jeff Cody Cc: kwolf@redhat.com, qemu-devel@nongnu.org, stefanha@redhat.com, agraf@suse.de On 03/14/14 16:36, Richard W.M. Jones wrote: > On Fri, Mar 14, 2014 at 06:50:37AM -0400, Jeff Cody wrote: >> On 32-bit hosts, some compilers will warn on too large integer constants >> for constants that are 64-bit in length. Explicitly put a 'ULL' suffix >> on those defines. >> -#define VHDX_FILE_SIGNATURE 0x656C696678646876 /* "vhdxfile" in ASCII */ >> +#define VHDX_FILE_SIGNATURE 0x656C696678646876ULL /* "vhdxfile" in ASCII */ > > I think it's better to use this C99-defined feature (from ): > > #define VHDX_FILE_SIGNATURE UINT64_C(0x656C696678646876) Here's some pointing to the standard(s)... "Unsigned long long" is a gnu-ism for C89. It's a standard part of C99. Last time I checked, qemu used the gnu89 dialect on all build hosts except SunOS. So, when you use an integer constant like 0x656C696678646876, that constant is undefined in C89. Namely, - 6.1.3.2 "integer constants" (in C89) describes the "ladder" only up to "unsigned long int" (unsuffixed hexadecimal), - ULONG_MAX need not be higher than (2^32-1) (5.2.4.2.1 "sizes of integral types "), which in fact happens to be the case in an -m32 build, - 6.1.3.2 "integer constants" (in C89) doesn't say anything about "extended integer types" (C99 does mention those), - in gnu89 dialect, gcc decides not to pick "long long unsigned" on its own for this constant (IOW gcc doesn't elect to "fill in" this undefined behavior for you even in gnu89 dialect). So, in gnu89 you really have no other choice than saying "long long unsigned" yourself (in this instance with the ULL suffix). In C99 this is not an issue, because the ladder goes up to "long long unsigned" (see 6.4.4.1 Integer constants), and that type must be able to represent (2^64-1) minimally (5.2.4.2.1 Sizes of integer types ). The "problem" with the proposed UINT64_C() is that it's C99 only. If we used C99 rather than gnu89, there would be no need for using UINT64_C(), the constant would simply work. (UINT64_C() might be part of gnu89 too, but then the ULL suffix, which is also gnu89, is just shorter.) In one sentence, the 0x656C696678646876 constant falls in the gnu89 \ c89 relative complement set for -m32, and gcc simply opts against automatically picking the "unsigned long long" type (which otherwise belongs to the same relative complement set of language features too), and leaves the behavior undefined. (That's my thinking at least.) Laszlo