Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: David Brown Newsgroups: comp.lang.c Subject: Re: Is 'extern' necessary? Date: Mon, 13 Feb 2017 13:14:34 +0100 Organization: A noiseless patient Spider Lines: 55 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Injection-Date: Mon, 13 Feb 2017 12:12:45 -0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="e04e5426bceb88344a663937ce34ac72"; logging-data="28633"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/w/HDG+Ish0VENOPMOM4ZAxDJ0fPHngoY=" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 In-Reply-To: Cancel-Lock: sha1:1tfZAZlmkZM360DOETcNr8tHFdw= Xref: csiph.com comp.lang.c:103789 On 11/02/17 00:34, Ian Collins wrote: > On 02/11/17 12:24 PM, BartC wrote: >> The 'extern' method is what I use exclusively when my tools >> auto-generate C code, as it's the method that more closely matches how I >> think about it: >> >> static int A [= expr]; // Defined here, not exported >> int B [= expr]; // Defined here, exported >> extern int C; // Defined elsewhere, imported >> >> Yet I rarely see 'extern' used in typical C code, and I need to >> understand how it's used in other people's code because I want to try >> and process C source. One good reason why you might not see "extern" so often in code is that it is only needed when data is shared directly amongst translation units, and that is usually considered a bad (or at least risky) practice. And one bad reason is that you (Bart) are not alone in misunderstanding how C linking and definitions work, and in thinking "it seems to work if I do this - it must be the correct way to write the code". >> >> (My generated code doesn't use headers, so if 3 modules want to use 'B' >> from my example, and 'B' is defined in module X, then: >> >> X contains: int B; // export >> Y contains: extern int B; // import >> Z contains: extern int B; // import >> >> Using headers like normal C code, it might be more like this: >> >> X sees: extern int B; // from #include "X.h" >> X contains: int B; // >> >> Y sees: extern int B; // from #include "X.h" >> Z sees: extern int B; // from #include "X.h" >> >> This combination I can understand. However no one else seems to write C >> like I do!) > > This is the typical use case. Yes. Typically you have the "extern" declarations in the header files, and you have the definitions (without "extern" or "static") in the source files. Any definition that does not have a matching "extern" declaration in an appropriate header, should be marked "static". Personally, I also put "extern" in my function declarations in headers. It is not required (since the lack of a function body already marks it as a non-defining declaration), and many people don't use it, but I feel it gives a clearer indication that this is a "global" function.