Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #103611 > unrolled thread

Is 'extern' necessary?

Started byBartC <bc@freeuk.com>
First post2017-02-10 17:16 +0000
Last post2017-02-11 03:17 -0800
Articles 20 on this page of 105 — 19 participants

Back to article view | Back to comp.lang.c


Contents

  Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-10 17:16 +0000
    Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-10 09:33 -0800
      Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-10 18:41 +0000
        Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-10 12:09 -0800
          Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-10 20:29 +0000
            Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-10 13:26 -0800
              Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-10 22:56 +0000
                Re: Is 'extern' necessary? jameskuyper@verizon.net - 2017-02-10 20:19 -0800
                  Re: Is 'extern' necessary? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-11 09:53 -0500
                Re: Is 'extern' necessary? Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-13 05:19 -0800
        Re: Is 'extern' necessary? jameskuyper@verizon.net - 2017-02-10 12:09 -0800
          Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-10 20:50 +0000
            Re: Is 'extern' necessary? supercat@casperkitty.com - 2017-02-10 13:09 -0800
            Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-10 13:33 -0800
            Re: Is 'extern' necessary? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-10 23:23 +0000
              Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-10 23:35 +0000
                Re: Is 'extern' necessary? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-11 00:34 +0000
              Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-13 12:41 +0100
                Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-13 13:14 +0000
                  Re: Is 'extern' necessary? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-13 14:05 +0000
                  Re: Is 'extern' necessary? jameskuyper@verizon.net - 2017-02-13 07:49 -0800
            Re: Is 'extern' necessary? jameskuyper@verizon.net - 2017-02-10 19:33 -0800
              Re: Is 'extern' necessary? supercat@casperkitty.com - 2017-02-11 09:41 -0800
                Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-11 10:19 -0800
                  Re: Is 'extern' necessary? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-11 13:39 -0500
                  Re: Is 'extern' necessary? supercat@casperkitty.com - 2017-02-12 10:10 -0800
        Re: Is 'extern' necessary? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2017-02-10 14:59 -0800
        Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-13 12:33 +0100
    Re: Is 'extern' necessary? Siri Cruise <chine.bleu@yahoo.com> - 2017-02-10 09:35 -0800
      Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-10 12:12 -0800
    Re: Is 'extern' necessary? jameskuyper@verizon.net - 2017-02-10 10:38 -0800
    Re: Is 'extern' necessary? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-10 21:10 +0000
      Re: Is 'extern' necessary? supercat@casperkitty.com - 2017-02-10 13:25 -0800
    Re: Is 'extern' necessary? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2017-02-10 14:53 -0800
      Re: Is 'extern' necessary? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2017-02-10 15:06 -0800
      Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-10 23:24 +0000
        Re: Is 'extern' necessary? Ian Collins <ian-news@hotmail.com> - 2017-02-11 12:34 +1300
          Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-13 13:14 +0100
            Re: Is 'extern' necessary? GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-02-13 13:44 +0100
              Re: Is 'extern' necessary? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-13 14:13 +0000
              Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-13 15:16 +0100
                Re: Is 'extern' necessary? GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-02-13 17:24 +0100
                  Re: Is 'extern' necessary? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-13 14:24 -0500
                  Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-13 23:29 +0100
              Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-13 11:06 -0800
              Re: Is 'extern' necessary? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2017-02-13 11:15 -0800
            Re: Is 'extern' necessary? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-13 11:48 -0500
              Re: Is 'extern' necessary? supercat@casperkitty.com - 2017-02-13 09:03 -0800
              Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-13 23:37 +0100
        Re: Is 'extern' necessary? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2017-02-10 15:40 -0800
        Re: Is 'extern' necessary? Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-13 05:09 -0800
          Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-13 13:46 +0000
            Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-13 09:52 -0800
              Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-13 19:19 +0000
                Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-13 11:34 -0800
                  Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-13 20:13 +0000
                Re: Is 'extern' necessary? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2017-02-13 13:11 -0800
                Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-14 00:33 +0100
                  Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-14 01:02 +0000
                    Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-14 09:28 +0100
                      Re: Is 'extern' necessary? Robert Wessel <robertwessel2@yahoo.com> - 2017-02-14 03:31 -0600
                      Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-14 11:42 +0000
                        Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-14 13:29 +0100
                          Re: Is 'extern' necessary? supercat@casperkitty.com - 2017-02-14 05:16 -0800
                            Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-14 14:51 +0100
                              Re: Is 'extern' necessary? supercat@casperkitty.com - 2017-02-14 07:24 -0800
                                Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-14 21:35 +0100
                                  Re: Is 'extern' necessary? James Kuyper <jameskuyper@verizon.net> - 2017-02-14 15:53 -0500
                                    Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-15 09:31 +0100
                                      Re: Is 'extern' necessary? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-15 11:36 -0500
                                        Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-15 09:12 -0800
                                          Re: Is 'extern' necessary? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-15 12:58 -0500
                                        Re: Is 'extern' necessary? supercat@casperkitty.com - 2017-02-15 10:01 -0800
                                          Re: Is 'extern' necessary? jameskuyper@verizon.net - 2017-02-15 10:55 -0800
                                            Re: Is 'extern' necessary? supercat@casperkitty.com - 2017-02-15 11:42 -0800
                                              Re: Is 'extern' necessary? jameskuyper@verizon.net - 2017-02-15 12:28 -0800
                                                Re: Is 'extern' necessary? supercat@casperkitty.com - 2017-02-15 13:58 -0800
                            Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-14 08:54 -0800
                        Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-14 08:51 -0800
                          Re: Is 'extern' necessary? Richard Heathfield <rjh@cpax.org.uk> - 2017-02-14 17:32 +0000
                            Re: Is 'extern' necessary? Gareth Owen <gwowen@gmail.com> - 2017-02-14 17:45 +0000
                          Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-14 21:38 +0100
                          Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-14 23:26 +0000
                            Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-14 16:33 -0800
                              Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-15 00:47 +0000
                        Re: Is 'extern' necessary? Jean-Marc Bourguet <jm@bourguet.org> - 2017-02-14 18:17 +0100
                          Re: Is 'extern' necessary? Keith Thompson <kst-u@mib.org> - 2017-02-14 09:47 -0800
                            Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-14 18:36 +0000
                              Re: Is 'extern' necessary? jameskuyper@verizon.net - 2017-02-14 11:20 -0800
                              Re: Is 'extern' necessary? supercat@casperkitty.com - 2017-02-14 11:42 -0800
                                Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-14 20:22 +0000
                              Re: Is 'extern' necessary? Robert Wessel <robertwessel2@yahoo.com> - 2017-02-14 17:58 -0600
                                Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-15 01:29 +0000
                                  Re: Is 'extern' necessary? Robert Wessel <robertwessel2@yahoo.com> - 2017-02-16 05:02 -0600
                                    Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-16 11:38 +0000
                                      Re: Is 'extern' necessary? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-16 14:37 +0000
                                        Re: Is 'extern' necessary? BartC <bc@freeuk.com> - 2017-02-16 15:43 +0000
                                          Re: Is 'extern' necessary? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-16 16:08 +0000
                                      Re: Is 'extern' necessary? GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-02-16 18:42 +0100
                                Re: Is 'extern' necessary? David Brown <david.brown@hesbynett.no> - 2017-02-15 09:47 +0100
                                  Re: Is 'extern' necessary? Robert Wessel <robertwessel2@yahoo.com> - 2017-02-16 05:05 -0600
            Re: Is 'extern' necessary? Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-15 16:53 -0800
      Re: Is 'extern' necessary? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-10 23:55 +0000
    Re: Is 'extern' necessary? Les Cargill <lcargill99@comcast.com> - 2017-02-10 19:24 -0600
    Re: Is 'extern' necessary? void <nathan.gothier@gmail.com> - 2017-02-11 03:17 -0800

Page 2 of 6 — ← Prev page 1 [2] 3 4 5 6  Next page →


#103812

Fromjameskuyper@verizon.net
Date2017-02-13 07:49 -0800
Message-ID<cfcb370d-8ab0-45b8-b5ef-81566e53630a@googlegroups.com>
In reply to#103794
On Monday, February 13, 2017 at 8:14:39 AM UTC-5, Bart wrote:
...
> Is a linker even an official part of the language? It does seem to be a 
> necessary component of most implementations.

A linker is not part of the language at all. It is part of most implementations
of the language. The language allows you to create a program containing
multiple translation units that must be linked together during translation
phase 8, and it specifies how the resulting program will work in terms of how
those translation units interact with each other. The standard leaves the
details of how this is implemented entirely up to the implementation. It
concerns itself solely with the connection between the contents of the C source
code files and the behavior of the translated program - it doesn't care how
that connection is achieved. If an implementation can generate the required
behavior without using an separate linker program, that's fine. If it can
generate that behavior without having any sub-component that could be called a
"linker", that's fine, too. But most real world implementation do use a linker
to implement that part of the C standard's requirements; and the ones that
don't generally have one or more subroutines that could reasonably be described
as "the linker".

[toc] | [prev] | [next] | [standalone]


#103654

Fromjameskuyper@verizon.net
Date2017-02-10 19:33 -0800
Message-ID<37272c08-9e01-4fb8-bcc5-6e63e0e723d6@googlegroups.com>
In reply to#103624
On Friday, February 10, 2017 at 3:50:11 PM UTC-5, Bart wrote:
> On 10/02/2017 20:09, jameskuyper@verizon.net wrote:
...
> > In 6.9, "external" means "outside of any function" (6.9p4), whereas in most
> > other parts of the standard it refers to "external linkage".
> 
> I remember that from a previous discussion. It comes up in K&R2 1.10 
> (p31): "An external variable... must be defined outside of any function. 
> ...The variable must also be declared in each function that wants to 
> access it...". And it goes on to suggest using an explicit 'extern' 
> statement.
> 
> I think that's just ramped up the confusion by a magnitude or so!

Your previous level of confusion about the C standard was already so high, that
I find it hard to believe that it could be increased by an order of magnitude
without destroying your sanity.

It's just a piece of jargon, no worse than most. The standard is actually quite
consistent about it. Outside of section 6.9, it almost never uses "external" in
any context where both meanings are possible, and in section 6.9 it explains the
different meaning that "external" has in that section (I say "almost" only
because there are so many uses of the term that I can't be sure I correctly
checked they all).

...
> > It makes things easier for the developer, however. Each of those rules
> > enables idioms that C programmers other than you find convenient.
> 
> What sort of idioms?

Putting what you would call the importing declaration of the object in a header
file, so you can be certain it's exactly the same in every TU that #includes the
header file, and also #including it in the same TU where what you would call the
the exporting definition of that same identifier. Because of the rules you find
so confusing, it's permissible for the importing declaration and the exporting
definition to reside in the same TU, but a diagnostic is mandatory if they
aren't compatible. Triggering that diagnostic if a mistake has been made is the
reason for putting them together in the same TU.

> I can see a couple of ways to share exported data in C. If module A 
> wants to share a named object with B:
> 
>    A.c:                        B.c:
> 
>    extern int abc;             extern int abc;   #include A.h
>    ....
>    int abc = 100;
> 
> But it also seems to work without extern:
> 
>    A.c:                        B.c:
> 
>    int abc;                    int abc;          #include A.h

Never try to guess whether something is correct, based upon whether it works.
This code has undefined behavior, for the reasons I've already given. That means
that the C standard imposes no requirements on such code. In particular, it
doesn't impose a requirement that it fail in any noticeable way. One of the most
common things that happens when the behavior is undefined, is that the code
works exactly the way that the author incorrectly thought it was required to
work. There's a reason why these incorrect expectations exist, and that's
because they match the way that many real implementations actually work. The
mistake comes from incorrectly concluding that because it works that way for
those implementations, it's required to work that way on all others.

Only by comparing your code with the requirements of the standard can you
determine whether it contains any of features that could make the behavior
undefined - no amount of testing will resolve that issue.

>    ....
>    int abc = 100;
> 
> Here, B doesn't know if abc belongs to B, or is imported from elsewhere. 
> A can assume that abc does belong because it's initialised. So object 
> files for both A and B appear to export abc, so only one is chosen by 
> the linker (since A contains init data for abc, that can be chosen).
> 
> The same thing applies when abc is a function. and the abc = 100 is 
> replaced a function body, except that now B /knows/ that abc has to 
> exist elsewhere. There is a link error if both A and B export abc with 
> init data or a function body.
> 
> So, why is any other idiom needed? The usage pattern required is simple.

To cope with linkers that don't behave the way you incorrectly believe they're
required to behave - which is true of many real-world linkers. I've even heard
of linkers which, when given two definitions of the same identifier with
external linkage in two different object files, will simply reserve the amount
of space required by the first definition, and use that amount of space for both
definitions, without even bothering to check whether the second definition
requires the same amount of space, much less whether they have compatible types
- the linker doesn't know anything about C's rules for compatible types. In fact, it doesn't know anything about C's types, period.

[toc] | [prev] | [next] | [standalone]


#103687

Fromsupercat@casperkitty.com
Date2017-02-11 09:41 -0800
Message-ID<f2c8f710-bdc3-4319-b018-757f54540b92@googlegroups.com>
In reply to#103654
On Friday, February 10, 2017 at 9:33:12 PM UTC-6, james...@verizon.net wrote:
>                   One of the most
> common things that happens when the behavior is undefined, is that the code
> works exactly the way that the author incorrectly thought it was required to
> work.

An even more common thing that happens when code executes behavior which is
not defined by the Standard is that it will work in a predictable fashion
which is defined by the target implementation, even if behavior would be
unpredictable on other implementations.

One of the biggest problems with C is that there hasn't been any effort to
formally characterize classes of implementations which support useful
guarantees beyond those required by the Standard.  This is made worse
by the fact that implementations seldom tried to document all of the 
guarantees that would seemingly-obviously follow from other documented
aspects of system operation.  If a build system specified that invoking
the the linker with certain options would cause it to treat multiple like-
named variables as a single variable, that would suggest a certain natural
behavior for code containing such symbols.  While it would be possible for
a build system to merges symbols ad document that it does so and yet still
launch nasal demons when running code that contains matching symbols, I
would not consider it unreasonable for programmers to treat the 
documentation of the symbol matching process as a definition of behavior
if the system documentation doesn't specify otherwise.

[toc] | [prev] | [next] | [standalone]


#103689

FromKeith Thompson <kst-u@mib.org>
Date2017-02-11 10:19 -0800
Message-ID<ln7f4wvbdn.fsf@kst-u.example.com>
In reply to#103687
supercat@casperkitty.com writes:
> On Friday, February 10, 2017 at 9:33:12 PM UTC-6, james...@verizon.net wrote:
>>                   One of the most
>> common things that happens when the behavior is undefined, is that the code
>> works exactly the way that the author incorrectly thought it was required to
>> work.
>
> An even more common thing that happens when code executes behavior which is
> not defined by the Standard is that it will work in a predictable fashion
> which is defined by the target implementation, even if behavior would be
> unpredictable on other implementations.

That's a subset of what James described (assuming that by "required" he
meant "required by the C standard", which I'm fairly sure he did).

> One of the biggest problems with C is that there hasn't been any effort to
> formally characterize classes of implementations which support useful
> guarantees beyond those required by the Standard.

POSIX is one such effort.

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#103693

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-02-11 13:39 -0500
Message-ID<a1f35916-c895-9e9f-206d-22ddd5d75da9@verizon.net>
In reply to#103689
On 02/11/2017 01:19 PM, Keith Thompson wrote:
> supercat@casperkitty.com writes:
>> On Friday, February 10, 2017 at 9:33:12 PM UTC-6, james...@verizon.net wrote:
>>>                   One of the most
>>> common things that happens when the behavior is undefined, is that the code
>>> works exactly the way that the author incorrectly thought it was required to
>>> work.
>>
>> An even more common thing that happens when code executes behavior which is
>> not defined by the Standard is that it will work in a predictable fashion
>> which is defined by the target implementation, even if behavior would be
>> unpredictable on other implementations.
>
> That's a subset of what James described (assuming that by "required" he
> meant "required by the C standard", which I'm fairly sure he did).

That's correct.

[toc] | [prev] | [next] | [standalone]


#103743

Fromsupercat@casperkitty.com
Date2017-02-12 10:10 -0800
Message-ID<607e3e66-c7e5-47d3-a376-20692419854e@googlegroups.com>
In reply to#103689
On Saturday, February 11, 2017 at 12:18:45 PM UTC-6, Keith Thompson wrote:
> supercat writes:
> > On Friday, February 10, 2017 at 9:33:12 PM UTC-6, James R. Kuyper wrote:
> >>                   One of the most
> >> common things that happens when the behavior is undefined, is that the code
> >> works exactly the way that the author incorrectly thought it was required to
> >> work.
> >
> > An even more common thing that happens when code executes behavior which is
> > not defined by the Standard is that it will work in a predictable fashion
> > which is defined by the target implementation, even if behavior would be
> > unpredictable on other implementations.
> 
> That's a subset of what James described (assuming that by "required" he
> meant "required by the C standard", which I'm fairly sure he did).

It's not a subset, since the situation I'm describing does not rely upon the
programmers having an "incorrect" belief about anything.  If code tests for
overlapping objects using something like:

    int overlaps(void *base1, void *base2, size_t size)
    {
      void *end1 = (char*)base1 + size;
      void *end2 = (char*)base2 + size;
      return end1 > base2 && end2 > base1; 
    }

rather than:

    int overlaps(void *base1, void *base2, size_t size)
    {
      while(--size)
      {
        if ((char*)base1+size == (char*)base2) return 1;
        if ((char*)base2+size == (char*)base1) return 1;
      }
      return 0;
    }

does that mean that the programmer incorrectly thought the Standard required
that implementations process the former construct usefully, or that the
programmer thought that the advantages of the former construct on platforms
where it would work were sufficient to justify limiting the program to such
platforms?

> > One of the biggest problems with C is that there hasn't been any effort to
> > formally characterize classes of implementations which support useful
> > guarantees beyond those required by the Standard.
> 
> POSIX is one such effort.

For hosted implementations POSIX may be useful, but it's far less so for
embedded applications which may not support all of the features that POSIX
would mandate.  Different kinds of applications benefit from different kinds
of features, so having finer granularity (e.g. being able to usefully say
that if implementation I supports features X and Y, but not Z, and program P
needs X and/or Y but not Z, then P should be able to run on I).

Some people seem to claim such granularity would cause Balkanization, but I
would suggest it would do the opposite.  If code could specify that it needs
a relatively weak guarantee regarding some behavior, such code could be
accommodated efficiently by more implementations than would be possible if
the only way code could specify that it needed any guarantee was for it to
also specify a lot of things that it didn't need.

[toc] | [prev] | [next] | [standalone]


#103638

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2017-02-10 14:59 -0800
Message-ID<o7lggb$e2f$1@dont-email.me>
In reply to#103617
On 2/10/2017 10:41 AM, BartC wrote:
>
> It mentions 'external definition'. What does that mean?
>
> Presumably it can't mean a definition with 'extern', because if I write:

No. The term is clearly defined in the standard document. "External 
definition" is a definition that is made "outside of any function", i.e. 
at file scope. E.g. 'static int i = 5;' at file scope is also an 
external definition.

>   extern int abc = 100;
>
> then gcc complains (but splitting it into extern int abc; int abc=100;
> is OK).

It issues a warning. It is just another of poorly thought through GCC 
warnings, created under the pressure of the masses who do not know how 
to use 'extern' properly.

> But with this extern, tentative, storage and linkage business, it's
> doing a good job of making it as fiendishly convoluted as possible.

Just forget about tentative definitions, at least in the context of this 
question. The "tentative definition" mechanism works entirely inside a 
translation unit. Officially, it has no effects that cross the boundary 
of a translation unit.

-- 
Best regards,
Andrey Tarasevich

[toc] | [prev] | [next] | [standalone]


#103786

FromDavid Brown <david.brown@hesbynett.no>
Date2017-02-13 12:33 +0100
Message-ID<o7s5fd$jui$1@dont-email.me>
In reply to#103617
On 10/02/17 19:41, BartC wrote:
> On 10/02/2017 17:33, Keith Thompson wrote:
>> BartC <bc@freeuk.com> writes:
>>> I've been trying to find out what the point of 'extern' is.
>>
>> N1570 6.9.2, tentative definitions.
> 
> It mentions 'external definition'. What does that mean?
> 
> Presumably it can't mean a definition with 'extern', because if I write:
> 
>   extern int abc = 100;
> 
> then gcc complains (but splitting it into extern int abc; int abc=100;
> is OK).
> 
> In my mind, file-scope objects can be declared in a module as either
> Local, Exported or Imported. Only the first two can be initialised in
> the module (initialising of an Imported object is up to the module that
> exports it).

In assembly, that is the common case - file-scope symbols are either
local, exported, or imported.  But in C, the concept is "linkage".
"extern" means that a symbol has external linkage.  You might be
declaring it as external linkage to export it, /or/ to import it.

So "extern" does /not/ mean "this identifier is defined externally".
The way to import a symbol is to have only an "extern" declaration.
Having a definition (without "static") is sufficient to export a symbol
- but you can happily also have an "extern" declaration there.  Most
people make use of that when the put their "extern" declarations in a
header file, and #include it in the source file that defines the object
as well as ones that use it.

> 
> I understand that in C, separate declarations that may appear
> conflicting are necessary, in order to have a shared declaration of X
> that can appear, via a shared header, in both modules A and B, where
> there is also a second, perhaps initialised definition of X in one of
> those modules.
> 
> But with this extern, tentative, storage and linkage business, it's
> doing a good job of making it as fiendishly convoluted as possible.
> Having issues hidden by a compiler, or multiple definitions taken care
> of by a linker, doesn't help in trying to understand.
> 

[toc] | [prev] | [next] | [standalone]


#103614

FromSiri Cruise <chine.bleu@yahoo.com>
Date2017-02-10 09:35 -0800
Message-ID<chine.bleu-6AB450.09350710022017@news.eternal-september.org>
In reply to#103611
In article <o7ksei$n0$1@dont-email.me>, BartC <bc@freeuk.com> wrote:

> It seems that most of the time you can get by without 'extern'. So when 
> is it necessary?

aleph.c:
    int beth = 0;

gimel.c:
    char *beth = "%4.2d";

    int daleth (void) {
        extern int beth; return ++beth;
    }

    char *he (void) {
        static char vav[100]; sprintf(vav, beth, daleth());
        return vav;
    }

zayin.h:
    extern int beth;

-- 
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
'I desire mercy, not sacrifice.'
Free the Amos Yee one.
Yeah, too bad about your so-called life. Ha-ha.

[toc] | [prev] | [next] | [standalone]


#103620

FromKeith Thompson <kst-u@mib.org>
Date2017-02-10 12:12 -0800
Message-ID<ln1sv5x0t4.fsf@kst-u.example.com>
In reply to#103614
Siri Cruise <chine.bleu@yahoo.com> writes:
> In article <o7ksei$n0$1@dont-email.me>, BartC <bc@freeuk.com> wrote:
>
>> It seems that most of the time you can get by without 'extern'. So when 
>> is it necessary?
>
> aleph.c:
>     int beth = 0;
>
> gimel.c:
>     char *beth = "%4.2d";
>
>     int daleth (void) {
>         extern int beth; return ++beth;
>     }
>
>     char *he (void) {
>         static char vav[100]; sprintf(vav, beth, daleth());
>         return vav;
>     }
>
> zayin.h:
>     extern int beth;

gimel.c has conflicting definitions for `beth`.  An example that's legal
C would be more compelling.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#103616

Fromjameskuyper@verizon.net
Date2017-02-10 10:38 -0800
Message-ID<71a80cd4-3a57-47da-90c8-4e79e6b2d7b3@googlegroups.com>
In reply to#103611
On Friday, February 10, 2017 at 12:16:55 PM UTC-5, Bart wrote:
> I've been trying to find out what the point of 'extern' is.
> 
> Usually, if you declare:
> 
>   int abc;
> 
> at filespec ...

"file scope"?

> ... in modules A and B, then you end up with one copy of 'abc' 
> shared across both modules. ...

"If an identifier declared with external linkage is used in an expression (other
than as part of the operand of a sizeof or _Alignof operator whose result is an
integer constant), somewhere in the entire program there shall be exactly one
external definition for the identifier; otherwise, there shall be no more than
one." (6.9p5). Violating a "shall" that occurs outside of a "Constraints"
section has undefined behavior (4p2).

Having a single copy of 'abc' shared between the two modules is one of the
infinitely many options permitted by "undefined behavior", and a relatively
common choice. Another option is that the linking of the program may fail, which
is also fairly popular. Other possibilities include having both of them exist,
but only one of them can be accessed from other translation units (TUs). The
other one would be accessible only from the TU it which it is defined.

> ... It doesn't matter which of A or B is abc's 
> 'home' module.
> 
> If one of them uses 'extern', then it's the same. But it fails when both 
> use 'extern'.
> 
> Unless one (or both) modules has a second declaration with just 'int 
> abc;'; that seems to have the effect of cancelling 'extern'. So it must 
> be doing something, but what?

You should define abc in exactly one TU, and you should declare it "extern" in
all of the other TUs where it is used. It indicates that the actual definition
is in a different TU. That "extern" declaration should be put in a header file,
and that header should be #included in every TU that uses 'abc' without defining
it. In addition, that header should also be #included in the one TU containing
the definition of 'abc'. The standard allows "extern int abc;" and "int abc;" to
coexist in the same TU, precisely in order to allow that header to be included.
The standard also makes it a constraint violation, with a diagnostic required,
if the two declarations don't give 'abc' compatible types. The reason for
#including it in the defining TU is so that such a diagnostic will be triggered
if a mistake has been made.

> When abc is initialised, then this is fine too (unless you initialise 
> the declaration with 'extern'), but now only one module can initialise 
> it; initialising both causes link errors.
> 
> It seems that most of the time you can get by without 'extern'. So when 
> is it necessary?

When you care about getting defined behavior when using linkers that work
differently from the way you have unjustifiably been expecting them to behave.

[toc] | [prev] | [next] | [standalone]


#103626

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-02-10 21:10 +0000
Message-ID<87inoh21ls.fsf@bsb.me.uk>
In reply to#103611
BartC <bc@freeuk.com> writes:

> I've been trying to find out what the point of 'extern' is.
>
> Usually, if you declare:
>
>  int abc;
>
> at filespec in modules A and B, then you end up with one copy of 'abc'
> shared across both modules.

No, you get undefined behaviour which can show up as a single object.
It is common for implementations to merge common definitions during
link, but not all of them do and gcc can be asked not to.

> If one of them uses 'extern', then it's the same. But it fails when
> both use 'extern'.

No, then it is correct and that the usual way to write such things:
defined in one TU and only declared in another.

> Unless one (or both) modules has a second declaration with just 'int
> abc;'; that seems to have the effect of cancelling 'extern'. So it
> must be doing something, but what?

extern is only really significant in that it allows you to write an
object declaration rather than a definition.  If C had no extern keyword
you would not be able to sat "x is an int defined somewhere else":

  extern int x;  // without the extern this is a definition of x

It won't prevent a declaration from also being a definition:

  extern int x = 42; // now a definition because of the initialiser

but that's not how it is usually used.

<snip>
> It seems that most of the time you can get by without 'extern'. So
> when is it necessary?

To turn a tentative definition into a declaration.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#103627

Fromsupercat@casperkitty.com
Date2017-02-10 13:25 -0800
Message-ID<08f7edaa-383f-441b-9723-48a37c11c6e9@googlegroups.com>
In reply to#103626
On Friday, February 10, 2017 at 3:11:03 PM UTC-6, Ben Bacarisse wrote:
> It won't prevent a declaration from also being a definition:
> 
>   extern int x = 42; // now a definition because of the initialiser
> 
> but that's not how it is usually used.

I wonder if that usage was included to facilitate adaptation of systems which
didn't require that code distinguish between importing and exporting symbols
and thus didn't use "extern" as the means of distinguishing between import
and export.  If the length of an array is determined by the data to be stored
therein, that would make it possible to declare and define a symbol in one
place:

    extern_if_not_foo_c unsigned char foo[] = { 1,3,5,7,2,4,6,8 };

[with extern_if_not_foo_c being a macro that is defined as "extern" except
when compiling foo.c] and have the compiler figure out the size based upon
the number of initializers would allowed code in any module to use "sizeof"
on the resulting array to determine its length.

[toc] | [prev] | [next] | [standalone]


#103636

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2017-02-10 14:53 -0800
Message-ID<o7lg60$df0$1@dont-email.me>
In reply to#103611
On 2/10/2017 9:16 AM, BartC wrote:
> I've been trying to find out what the point of 'extern' is.
>
> Usually, if you declare:
>
>  int abc;
>
> at filespec in modules A and B, then you end up with one copy of 'abc'
> shared across both modules. It doesn't matter which of A or B is abc's
> 'home' module.

No, you will end up with a constraint violation. C language prohibits 
this, although it lists it as a "popular extension" in a non-normative 
appendix of the language standard.

(It is often incorrectly claimed that "tentative definition" mechanism 
in C allows this. In reality, it doesn't. However, this is allegedly a 
side-effect of the approach compilers use to implement tentative 
definitions in C. Nevertheless, it is illegal.)

> If one of them uses 'extern', then it's the same.

Then it is correct (as opposed to your previous example).

> But it fails when both use 'extern'.

Certainly, since it leaves your object undefined.

> Unless one (or both) modules has a second declaration with just 'int
> abc;'; that seems to have the effect of cancelling 'extern'. So it must
> be doing something, but what?

See above.

> When abc is initialised, then this is fine too (unless you initialise
> the declaration with 'extern'), but now only one module can initialise
> it; initialising both causes link errors.

Of course. Presence of an initializer makes it into a definition, even 
in presence of 'extern'.

> It seems that most of the time you can get by without 'extern'. So when
> is it necessary?

It is necessary to create non-defining declarations of global variables:

     extern int i; // Declaration, not a definition

Additionally, it can be used to refer to a hidden name of a global variable

     int i;

     void foo()
     {
       int i; // Hides global `i`

       {
         extern int i; // Refers to global `i` and brings it to
                       // this scope
         ...
       }
     }

-----

As for the declaration-definition model used in standard C, you can take 
a look at the description provided in C99 rationale:

"
The definition model to be used for objects with external linkage was a 
major C89 standardization issue. The basic problem was to decide which 
declarations of an object define storage for the object, and which 
merely reference an existing object. A related problem was whether 
multiple definitions of storage are allowed, or only one is acceptable. 
Pre-C89 implementations exhibit at least four different models, listed 
here in order of increasing restrictiveness:

*Common* Every object declaration with external linkage, regardless of 
whether the keyword 'extern' appears in the declaration, creates a 
definition of storage. When all of the modules are combined together, 
each definition with the same name is located at the same address in
memory. (The name is derived from common storage in Fortran.) This model 
was the intent of the original designer of C, Dennis Ritchie.

*Relaxed Ref/Def* The appearance of the keyword 'extern' in a 
declaration, regardless of whether it is used inside or outside of the 
scope of a function, indicates a pure reference (ref), which does not 
define storage. Somewhere in all of the translation units, at least one 
definition (def) of the object must exist. An external definition is 
indicated by an object declaration in file scope containing no storage 
class indication. A reference without a corresponding definition is
an error. Some implementations also will not generate a reference for 
items which are declared with the 'extern' keyword but are never used in 
the code. The UNIX operating system C compiler and linker implement this 
model, which is recognized as a common extension to the C language (see 
§J.5.11). UNIX C programs which take advantage of this model are 
standard conforming in their environment, but are not maximally portable 
(not strictly conforming).

*Strict Ref/Def* This is the same as the relaxed ref/def model, save 
that only one definition is allowed. Again, some implementations may 
decide not to put out references to items that are not used. This is the 
model specified in K&R.

*Initialization* This model requires an explicit initialization to 
define storage. All other declarations are references.

Figure 6.1 demonstrates the differences between the models.

The Standard model is a combination of features of the strict ref/def 
model and the initialization model. As in the strict ref/def model, only 
a single translation unit contains the definition of a given object 
because many environments cannot effectively or efficiently support the 
“distributed definition” inherent in the common or relaxed ref/def 
approaches. However, either an initialization, or an appropriate 
declaration without storage class specifier (see §6.9), serves as the 
external definition. This composite approach was chosen to accommodate 
as wide a range of environments and existing implementations as possible.
"

You apparently mistakenly believe that C uses "Common" model, which 
admittedly was the original intent of Dennis Ritchie (and probably 
existed in C of CRM era), but standard C adopted a different model.

-- 
Best regards,
Andrey Tarasevich

[toc] | [prev] | [next] | [standalone]


#103639

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2017-02-10 15:06 -0800
Message-ID<o7lgtn$ivh$1@dont-email.me>
In reply to#103636
On 2/10/2017 2:53 PM, Andrey Tarasevich wrote:
>...
> As for the declaration-definition model used in standard C, you can take
> a look at the description provided in C99 rationale:
>
> "
> The definition model to be used for objects with external linkage was a
> major C89 standardization issue. The basic problem was to decide which
> declarations of an object define storage for the object, and which
> merely reference an existing object. A related problem was whether
> multiple definitions of storage are allowed, or only one is acceptable.
> Pre-C89 implementations exhibit at least four different models, listed
> here in order of increasing restrictiveness:
>
> *Common* Every object declaration with external linkage, regardless of
> whether the keyword 'extern' appears in the declaration, creates a
> definition of storage. When all of the modules are combined together,
> each definition with the same name is located at the same address in
> memory. (The name is derived from common storage in Fortran.) This model
> was the intent of the original designer of C, Dennis Ritchie.
>
> *Relaxed Ref/Def* The appearance of the keyword 'extern' in a
> declaration, regardless of whether it is used inside or outside of the
> scope of a function, indicates a pure reference (ref), which does not
> define storage. Somewhere in all of the translation units, at least one
> definition (def) of the object must exist. An external definition is
> indicated by an object declaration in file scope containing no storage
> class indication. A reference without a corresponding definition is
> an error. Some implementations also will not generate a reference for
> items which are declared with the 'extern' keyword but are never used in
> the code. The UNIX operating system C compiler and linker implement this
> model, which is recognized as a common extension to the C language (see
> §J.5.11). UNIX C programs which take advantage of this model are
> standard conforming in their environment, but are not maximally portable
> (not strictly conforming).
>
> *Strict Ref/Def* This is the same as the relaxed ref/def model, save
> that only one definition is allowed. Again, some implementations may
> decide not to put out references to items that are not used. This is the
> model specified in K&R.
>
> *Initialization* This model requires an explicit initialization to
> define storage. All other declarations are references.
>
> Figure 6.1 demonstrates the differences between the models.
>
> The Standard model is a combination of features of the strict ref/def
> model and the initialization model. As in the strict ref/def model, only
> a single translation unit contains the definition of a given object
> because many environments cannot effectively or efficiently support the
> “distributed definition” inherent in the common or relaxed ref/def
> approaches. However, either an initialization, or an appropriate
> declaration without storage class specifier (see §6.9), serves as the
> external definition. This composite approach was chosen to accommodate
> as wide a range of environments and existing implementations as possible.
> "
>
> You apparently mistakenly believe that C uses "Common" model, which
> admittedly was the original intent of Dennis Ritchie (and probably
> existed in C of CRM era), but standard C adopted a different model.
>

A correction:

Your description fits the "Relaxed Ref/Def" model, which is also 
mentioned as a popular extension in the above Rationale.

Yet, it is not the model adopted by standard C.

-- 
Best regards,
Andrey Tarasevich

[toc] | [prev] | [next] | [standalone]


#103643

FromBartC <bc@freeuk.com>
Date2017-02-10 23:24 +0000
Message-ID<o7li0r$m52$1@dont-email.me>
In reply to#103636
On 10/02/2017 22:53, Andrey Tarasevich wrote:
> On 2/10/2017 9:16 AM, BartC wrote:
>> I've been trying to find out what the point of 'extern' is.
>>
>> Usually, if you declare:
>>
>>  int abc;
>>
>> at filespec in modules A and B, then you end up with one copy of 'abc'
>> shared across both modules. It doesn't matter which of A or B is abc's
>> 'home' module.
>
> No, you will end up with a constraint violation. C language prohibits
> this, although it lists it as a "popular extension" in a non-normative
> appendix of the language standard.
>
> (It is often incorrectly claimed that "tentative definition" mechanism
> in C allows this. In reality, it doesn't. However, this is allegedly a
> side-effect of the approach compilers use to implement tentative
> definitions in C. Nevertheless, it is illegal.)
>
>> If one of them uses 'extern', then it's the same.
>
> Then it is correct (as opposed to your previous example).

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.

(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!)

> Additionally, it can be used to refer to a hidden name of a global variable
>
>     int i;
>
>     void foo()
>     {
>       int i; // Hides global `i`
>
>       {
>         extern int i; // Refers to global `i` and brings it to
>                       // this scope
>         ...
>       }
>     }

That's an interesting use. But I suspect very little used.


> Pre-C89 implementations exhibit at least four different models, listed
> here in order of increasing restrictiveness:
>
> *Common* Every object declaration with external linkage, regardless of
> whether the keyword 'extern' appears in the declaration, creates a
> definition of storage. When all of the modules are combined together,
> each definition with the same name is located at the same address in
> memory. (The name is derived from common storage in Fortran.) This model
> was the intent of the original designer of C, Dennis Ritchie.

Yes. I liked Fortran...

> *Relaxed Ref/Def* The appearance of the keyword 'extern' in a

> *Strict Ref/Def* This is the same as the relaxed ref/def model, save

> *Initialization* This model requires an explicit initialization to
> define storage. All other declarations are references.
....

This is heavy stuff. But is it really necessary; do linkers really work 
like this?

Sure all that's needed is a Local, Imported, Exported model?

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#103644

FromIan Collins <ian-news@hotmail.com>
Date2017-02-11 12:34 +1300
Message-ID<eg7107Fbmb2U1@mid.individual.net>
In reply to#103643
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.
>
> (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.
-- 
Ian

[toc] | [prev] | [next] | [standalone]


#103789

FromDavid Brown <david.brown@hesbynett.no>
Date2017-02-13 13:14 +0100
Message-ID<o7s7rt$rup$1@dont-email.me>
In reply to#103644
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.


[toc] | [prev] | [next] | [standalone]


#103790

FromGOTHIER Nathan <nathan.gothier@gmail.com>
Date2017-02-13 13:44 +0100
Message-ID<20170213134423.3e115bb6b08b18a261c46bae@gmail.com>
In reply to#103789
On Mon, 13 Feb 2017 13:14:34 +0100
David Brown <david.brown@hesbynett.no> wrote:

> 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".

I agree the linkage definition is rather obscure in the C standard.


> 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".

If you put a non "extern" object with "static", its lifetime is longer than
necessary and you prevent the compiler to free unused memory space for example
when leaving a block. The linkage defines links between objects like pointers.
It is useful to distinguish objects named with the same identifier.


> 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.

Prototypes should always be declared as "extern" since it points to a previous
definition.

[toc] | [prev] | [next] | [standalone]


#103802

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-02-13 14:13 +0000
Message-ID<87fujitbzn.fsf@bsb.me.uk>
In reply to#103790
GOTHIER Nathan <nathan.gothier@gmail.com> writes:
> On Mon, 13 Feb 2017 13:14:34 +0100
> David Brown <david.brown@hesbynett.no> wrote:
<snip>
>> 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.
>
> Prototypes should always be declared as "extern" since it points to a previous
> definition.

I have a feeling that it is more common to leave extern off from
prototype declarations.  Even if it's not as common as I imagine, I
would expect everyone reading C to be used to it.  In short, I think a
blank "should" is too strong.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


Page 2 of 6 — ← Prev page 1 [2] 3 4 5 6  Next page →

Back to top | Article view | comp.lang.c


csiph-web