From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 130209 invoked by alias); 22 Jan 2018 09:54:06 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 130189 invoked by uid 89); 22 Jan 2018 09:54:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.1 required=5.0 tests=BAYES_00,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_PASS,UNSUBSCRIBE_BODY autolearn=no version=3.3.2 spammy=controlling, H*f:sk:5A65A1A, sk:davidw, H*Ad:U*david X-HELO: mailfilter05.hatteland.com Received: from mailfilter05.hatteland.com (HELO mailfilter05.hatteland.com) (213.162.250.24) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 22 Jan 2018 09:54:02 +0000 Received: from localhost (localhost [127.0.0.1]) by mailfilter05.hatteland.com (Postfix) with ESMTP id 2C130F4F2E; Mon, 22 Jan 2018 10:54:00 +0100 (CET) Received: from mailfilter05.hatteland.com (localhost [127.0.0.1]) by mailfilter05.hatteland.com (Postfix) with ESMTP id 8E2C9F4ED9; Mon, 22 Jan 2018 10:53:58 +0100 (CET) Received: from JHSVMHUB01.netsentral.no (unknown [172.21.1.101]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mailfilter05.hatteland.com (Postfix) with ESMTPS id 8B01AF4E87; Mon, 22 Jan 2018 10:53:58 +0100 (CET) Received: from [192.168.0.77] (172.21.20.100) by e2010.hatteland.com (172.21.1.25) with Microsoft SMTP Server (TLS) id 14.3.224.2; Mon, 22 Jan 2018 10:53:58 +0100 Subject: Re: extern const initialized warns in C To: Jay K , gcc References: <5A65A1AC.9010800@westcontrol.com> From: David Brown Message-ID: <0ae87d93-0b7f-c3aa-eaea-13299c2d528e@westcontrol.com> Date: Mon, 22 Jan 2018 09:54:00 -0000 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.5.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 8bit X-SW-Source: 2018-01/txt/msg00153.txt.bz2 On 22/01/2018 10:31, Jay K wrote: > > By this argument there is a missing warning for the equivalent: > >   const int foo = 123; > > with no previous extern declaration. I would like to see such a warning. There is "-Wmissing-declarations", but that applies only to functions and not to objects. (Note that in C++, "const" objects without an "extern" declaration are effectively "static" - in C, without the storage-class specifier const objects have external linkage.) > > As well, there is no warning in C++. > All three constructs are equivalent, yet only one gets a warning. No, they are not the same - in C++ the linkage of a const is static unless you explicitly say "extern", and in C it is external unless you explicitly say "static". Thus in "extern const int foo = 123;", the "extern" has a significant effect in C++ but in C it does nothing (other than inform the reader). I would like to see the warning having a controlling flag. It could perhaps be on by default in C and off by default in C++ to get the same effect as today - and then users can fine-tune to fit their style. > > Interesting point, that I had not realized, and with an often acceptable > workaround, however also there exist coding conventions that prohibit use of static. I have never heard of such a thing in a coding standard. C++ conventions might encourage the use of anonymous namespaces rather than C-style "static" declarations, but that would not apply to C. I would consider a coding convention that discouraged static to be seriously broken. > Instead they "hide" things by omitting them from headers only. That is madness. The symbols still have global linkage across the program, and you will get all sorts of problems when one file uses the same "local" identifier as another. If you are lucky, your linker will tell you of the crash - but if you have enabled "common" data (i.e., you don't have the "-fno-common" flag) and have used the same identifier for two different "local" objects without explicit initialisation, you are going to have some serious and very hard to find bugs. If someone asks you to write to such a coding convention, do your best to refuse. > > That can still be worked around, just put the declaration right before the definition, > in the same source file. > > I realize there are many arguments for and against file level static. > There are no /good/ arguments against file-level static in C, except perhaps temporarily while debugging (it can be easier to view non-static data in a debugger). Any time file-level static can be used, it /should/ be used. IMHO, of course. mvh., David >  - Jay > > > From: David Brown > Sent: Monday, January 22, 2018 8:32 AM > To: Jay K; gcc > Subject: Re: extern const initialized warns in C > > > On 21/01/18 08:12, Jay K wrote: >> extern const int foo = 123; >> >> >> >> Why does this warn? >> This is a valid portable form, with the same meaning >> across all compilers, and, importantly, portably >> to C and C++. >> >> I explicitly do not want to say: >> >>    const int foo = 123 >> >> because I want the code to be valid and have the same meaning >> in C and C++ (modulo name mangling). >> >> I end up with: >> >> // Workaround gcc warning. >> #ifdef __cplusplus >> #define EXTERN_CONST extern const >> #else >> #define EXTERN_CONST const >> #endif >> >> >> EXTERN_CONST int foo = 123; >> >> and having to explain it to people. >> > > > > > 45977 – "warning: 'i' initialized and declared 'extern ... > gcc.gnu.org > GCC Bugzilla – Bug 45977 "warning: 'i' initialized and declared 'extern'" could use a separate warning flag controlling it Last modified: 2017-07-26 15:36:22 UTC > > This suggests that gcc authors consider mixing "extern" and > initialization to be such bad style that the compiler warns by default. >  But the "bug" is that there is no flag to turn off this warning. > (Ideally every warning should have a matching flag, even if the warning > is enabled by default.) > > Usually you do not want to have "extern" and initialisation in the same > line - it indicates a questionable organisation of your sources which is > more likely to be error-prone than the standard idioms.  (I say > "questionable", not necessarily wrong - but certainly I would question > it if I saw it in source code.) > > Normally you want: > > // file.h > // declaration, not definition > extern const int foo; > > // file.c > #include > // definition > const int foo = 123; > > // otherfile.c > #include > int usefoo(void) { return foo; } > > > The key advantages of this sort of setup are a cleaner separation > between declarations (which you need to /use/ things) and the > definitions (which should normally only exist once in the program - > certainly for C).  The declarations and definitions only exist in one > place, and they are checked for consistency - there are no "extern" > declarations lying around in C files that might get out of step from > changes in the headers or other files with definitions. > > To be consistent with this, and to work consistently with C and C++, I > have a strict policy that a C (or C++) file never contains  declarations > without definitions (and initialisations as needed), with each > definition either also declared as "extern" in a matching header file, > or it is declared as "static". > > This sort of arrangement is very common - though many people are lazy > about using "static".  (In C++, you can also use anonymous namespaces, > but "static" works for consistency between C and C++.) > > > Still, gcc should have a flag to disable this warning if you have reason > to use "extern const int foo = 123;" - it is, after all, correctly > defined C code. > > > >> $ cat 1.c >> extern const int foo = 123; >> $ $HOME/gcc720/bin/gcc -c -S 1.c >> 1.c:1:18: warning: 'foo' initialized and declared 'extern' >>   extern const int foo = 123; >>                    ^~~ >> $ $HOME/gcc720/bin/gcc -c -S -xc++ -Wall -pedantic 1$ $HOME/gcc720/bin/gcc -v >> Using built-in specs. >> >> COLLECT_GCC=/Users/jay/gcc720/bin/gcc >> COLLECT_LTO_WRAPPER=/Users/jay/gcc720/libexec/gcc/x86_64-apple-darwin16.7.0/7.2.0/lto-wrapper >> Target: x86_64-apple-darwin16.7.0 >> Configured with: ../gcc-7.2.0/configure -prefix=/Users/jay/gcc720 -disable-nls -disable-bootstrap >> Thread model: posix >> gcc version 7.2.0 (GCC) $ >> >> >> Thank you, >>   - Jay >> >> >> >> >> > > >