From patchwork Thu Aug 31 15:28:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laszlo Ersek X-Patchwork-Id: 9932377 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2A4336022E for ; Thu, 31 Aug 2017 15:29:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0F029281B7 for ; Thu, 31 Aug 2017 15:29:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 01C26287EC; Thu, 31 Aug 2017 15:29:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 04A47281B7 for ; Thu, 31 Aug 2017 15:29:16 +0000 (UTC) Received: from localhost ([::1]:56321 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dnRP9-0001OU-CR for patchwork-qemu-devel@patchwork.kernel.org; Thu, 31 Aug 2017 11:29:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35403) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dnROX-0001OD-Ld for qemu-devel@nongnu.org; Thu, 31 Aug 2017 11:28:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dnROU-0000zR-FT for qemu-devel@nongnu.org; Thu, 31 Aug 2017 11:28:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:35504) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dnROU-0000z2-7B for qemu-devel@nongnu.org; Thu, 31 Aug 2017 11:28:34 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 89D106146D for ; Thu, 31 Aug 2017 15:28:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 89D106146D Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=lersek@redhat.com Received: from lacos-laptop-7.usersys.redhat.com (ovpn-116-89.phx2.redhat.com [10.3.116.89]) by smtp.corp.redhat.com (Postfix) with ESMTP id 945125D9CA; Thu, 31 Aug 2017 15:28:29 +0000 (UTC) To: Markus Armbruster , =?UTF-8?Q?Marc-Andr=c3=a9_Lureau?= References: <20170825105913.4060-1-marcandre.lureau@redhat.com> <20170825105913.4060-5-marcandre.lureau@redhat.com> <87val5gta4.fsf@dusky.pond.sub.org> <844220409.5983155.1504095111596.JavaMail.zimbra@redhat.com> <8760d5dx8f.fsf@dusky.pond.sub.org> <243440747.6086481.1504099179043.JavaMail.zimbra@redhat.com> <878ti0ku0n.fsf@dusky.pond.sub.org> From: Laszlo Ersek Message-ID: <1cf6ce88-0dd4-6d40-60bf-8b78f02a2fa0@redhat.com> Date: Thu, 31 Aug 2017 17:28:28 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 In-Reply-To: <878ti0ku0n.fsf@dusky.pond.sub.org> Content-Language: en-US X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 31 Aug 2017 15:28:32 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: Re: [Qemu-devel] [PATCH v2 04/14] qlit: remove compound literals X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP On 08/31/17 10:42, Markus Armbruster wrote: > Marc-André Lureau writes: > >> Hi >> >> ----- Original Message ----- >>> Marc-André Lureau writes: >>> >>>> Hi >>>> >>>> ----- Original Message ----- >>>>> Marc-André Lureau writes: >>>>> >>>>>> They are not considered constant expressions in C, producing an error >>>>>> when compiling a const QLit. >>>>> >>>>> A const QLit? Do you mean a non-const one? >>>> >>>> Really a const QLitObject: >>>> >>>> >>>> const QLitObject qmp_schema_qlit = QLIT_QLIST(((QLitObject[]) { >>>> QLIT_QNULL, >>>> {} >>>> })); >>>> >>>> qmp-introspect.c:17:63: error: initializer element is not constant >>>> const QLitObject qmp_schema_qlit = QLIT_QLIST(((QLitObject[]) { >>>> ^ >>>> Removing the "compound literals" fixes this error. >>> >>> Does QLIT_QLIST(((const QLitObject[]) { ... } work? >> >> No. Even if I put "const" all over the place (in member, in compound type etc). >> >> Give it a try, see if you can make it const, I am out of luck. > > The commit message's explanation is wrong. This isn't about const at > all, it's about "constant expressions", which are something else > entirely. > > For what it's worth, clang is cool with the compound literals. On > Fedora 26 with a minimized test case (appended): > > $ clang -c -g -O -Wall compound-lit.c > $ gcc -c -g -O -Wall compound-lit.c > compound-lit.c:30:37: error: initializer element is not constant > .value.qdict = (QLitDictEntry[]){ > ^ > compound-lit.c:30:37: note: (near initialization for ‘(anonymous).value’) > > GCC bug or not? A search of the GCC Bugzilla finds > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71713 > > Copying a few notorious language lawyers^W^W^Wtrusted advisers. > > Even if this turns out to be a gcc bug, we'll have to work around it. > But the work-around needs a comment then. > > In any case, the commit message needs fixing. > > > > enum { > QTYPE_NONE, QTYPE_QSTRING, QTYPE_QDICT, > }; > > typedef struct QLitDictEntry QLitDictEntry; > typedef struct QLitObject QLitObject; > > struct QLitObject { > int type; > union { > const char *qstr; > QLitDictEntry *qdict; > } value; > }; > > struct QLitDictEntry { > const char *key; > QLitObject value; > }; > > QLitObject qlit1 = (QLitObject){ > .type = QTYPE_QDICT, > .value.qdict = (QLitDictEntry[]){ > { "foo", {} }, > {} > }}; > > QLitObject qlit2 = (QLitObject){ > .type = QTYPE_QDICT, > .value.qdict = (QLitDictEntry[]){ > { "foo", (QLitObject){} }, > {} > }}; > (1) When discussing standards conformance, please drop the {} construct; it is a GNUism. Replacing it with { 0 } works in all contexts, and conforms to the standard. (Not trying to be pedantic here, but it does elicit extra warnings from my gcc command line gcc -std=c99 -pedantic -Wall -Wextra -fsyntax-only (2) Let's see what the standard says: 6.5.2.5 Compound literals Constraints 3 If the compound literal occurs outside the body of a function, the initializer list shall consist of constant expressions. In the initialization of "qlit1", one element of the initializer list (namely for .value.qdict) is [1] (QLitDictEntry[]) { { "foo", { 0 } }, { 0 } } Is this a constant expression? 6.6 Constant expressions 7 More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following: - an arithmetic constant expression, - a null pointer constant, - an address constant, or - an address constant for an object type plus or minus an integer constant expression. Now, is [1] an address constant? 6.6 Constant expressions 9 An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration, or a pointer to a function designator; it shall be created explicitly using the unary & operator or an integer constant cast to pointer type, or implicitly by the use of an expression of array or function type. The array-subscript [] and member-access . and -> operators, the address & and indirection * unary operators, and pointer casts may be used in the creation of an address constant, but the value of an object shall not be accessed by use of these operators. "expression of array [...] type" applies; question is: - is [1] an lvalue designating an object of static storage duration? 6.5.2.5 Compound literals Semantics 5 If the type name specifies an array of unknown size, the size is determined by the initializer list as specified in 6.7.8, and the type of the compound literal is that of the completed array type. Otherwise (when the type name specifies an object type), the type of the compound literal is that specified by the type name. In either case, the result is an lvalue. So, an lvalue [1] is. 6 The value of the compound literal is that of an unnamed object initialized by the initializer list. If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block. Static storage duration is therefore also proven; the initializer [1] that we provide for ".value.qdict" *is* a constant expression. (3) However, on my side at least -- RHEL-7.4 --, the initializer for ".value.qdict" is not what gcc complains about, in the initialization of "qlit1"! The problem is the *outer* compound literal. *That* is indeed not a constant expression; if you review 6.6p7 above, it does not fit any of the allowed cases. However, the outer compound literal doesn't buy us anything! If you change the code like this, it compiles without a hitch: (I ignored "qlit2" for this discussion.) Thanks Laszlo --- xx.c 2017-08-31 17:23:05.145481557 +0200 +++ yy.c 2017-08-31 17:25:14.839088894 +0200 @@ -18,7 +18,7 @@ QLitObject value; }; -QLitObject qlit1 = (QLitObject){ +QLitObject qlit1 = { .type = QTYPE_QDICT, .value.qdict = (QLitDictEntry[]){ { "foo", { 0 } },