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


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

To include or not to include

Started byJames Harris <james.harris.1@gmail.com>
First post2016-09-23 10:45 +0100
Last post2016-09-23 11:37 -0400
Articles 20 on this page of 70 — 16 participants

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


Contents

  To include or not to include James Harris <james.harris.1@gmail.com> - 2016-09-23 10:45 +0100
    Re: To include or not to include David Brown <david.brown@hesbynett.no> - 2016-09-23 12:43 +0200
      Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-23 12:17 +0100
        Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-23 13:32 +0100
          Re: To include or not to include David Brown <david.brown@hesbynett.no> - 2016-09-23 14:57 +0200
          Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-24 20:34 +0100
            Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-24 23:55 +0100
              Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-25 01:43 +0100
                Re: To include or not to include Ian Collins <ian-news@hotmail.com> - 2016-09-25 14:38 +1300
                Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-25 11:42 +0100
                  Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-25 11:58 +0100
                    Re: To include or not to include James Harris <james.harris.1@gmail.com> - 2016-09-25 14:06 +0100
                      Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-25 15:15 +0100
                        Re: To include or not to include Reinhardt Behm <rbehm@hushmail.com> - 2016-09-25 23:33 +0800
                          Re: To include or not to include Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2016-09-25 10:04 -0600
                            Re: To include or not to include Reinhardt Behm <rbehm@hushmail.com> - 2016-09-26 00:21 +0800
                            Re: To include or not to include "James R. Kuyper" <jameskuyper@verizon.net> - 2016-09-25 13:17 -0400
                        Re: To include or not to include James Harris <james.harris.1@gmail.com> - 2016-09-26 00:18 +0100
                          Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-26 17:55 +0100
                            Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-26 20:07 +0100
                            Re: To include or not to include supercat@casperkitty.com - 2016-09-26 12:13 -0700
                            Re: To include or not to include James Harris <james.harris.1@gmail.com> - 2016-09-27 01:25 +0100
                              Re: To include or not to include supercat@casperkitty.com - 2016-09-26 18:05 -0700
                                Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-27 14:27 +0100
                                  Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-27 14:49 +0100
                                    Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-27 15:15 +0100
                                      Re: To include or not to include Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-27 07:42 -0700
                                        Re: To include or not to include Keith Thompson <kst-u@mib.org> - 2016-09-27 09:30 -0700
                                          Re: To include or not to include Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-27 10:06 -0700
                                      Re: To include or not to include supercat@casperkitty.com - 2016-09-27 08:12 -0700
                                        Re: To include or not to include Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-28 10:46 -0700
                                      Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-27 17:55 +0100
                                        Re: To include or not to include supercat@casperkitty.com - 2016-09-27 10:19 -0700
                                        Re: To include or not to include Keith Thompson <kst-u@mib.org> - 2016-09-27 11:42 -0700
                                          Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-27 19:57 +0100
                                            Re: To include or not to include Keith Thompson <kst-u@mib.org> - 2016-09-27 12:38 -0700
                                              Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-27 21:00 +0100
                                                Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-28 01:50 +0100
                                                  Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-28 10:55 +0100
                                              Re: To include or not to include Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-27 13:33 -0700
                                                Re: To include or not to include Ike Naar <ike@iceland.freeshell.org> - 2016-09-28 19:13 +0000
                                            Re: To include or not to include supercat@casperkitty.com - 2016-09-27 12:38 -0700
                                          Re: To include or not to include James Harris <james.harris.1@gmail.com> - 2016-09-27 20:57 +0100
                                  Re: To include or not to include supercat@casperkitty.com - 2016-09-27 07:25 -0700
                                    Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-28 00:28 +0100
                                      Re: To include or not to include supercat@casperkitty.com - 2016-09-30 07:53 -0700
                                        Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-30 16:06 +0100
                              Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-27 13:53 +0100
                                Re: To include or not to include James Harris <james.harris.1@gmail.com> - 2016-09-30 19:46 +0100
                                  Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-30 20:27 +0100
                      Re: To include or not to include Reinhardt Behm <rbehm@hushmail.com> - 2016-09-25 23:27 +0800
                        Re: To include or not to include Jerry Stuckle <jstucklex@attglobal.net> - 2016-09-25 11:38 -0400
                          Re: To include or not to include Reinhardt Behm <rbehm@hushmail.com> - 2016-09-25 23:40 +0800
                  Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-25 15:06 +0100
                    Re: To include or not to include Jerry Stuckle <jstucklex@attglobal.net> - 2016-09-25 11:49 -0400
                      Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-25 18:05 +0100
                        Re: To include or not to include Jerry Stuckle <jstucklex@attglobal.net> - 2016-09-25 16:42 -0400
                          Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-25 21:53 +0100
                            Re: To include or not to include Jerry Stuckle <jstucklex@attglobal.net> - 2016-09-25 17:57 -0400
                    Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-25 21:20 +0100
                      Re: To include or not to include BartC <bc@freeuk.com> - 2016-09-25 21:49 +0100
                        Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-26 00:40 +0100
        Re: To include or not to include David Brown <david.brown@hesbynett.no> - 2016-09-23 14:56 +0200
    Re: To include or not to include Richard Heathfield <rjh@cpax.org.uk> - 2016-09-23 13:31 +0100
      Re: To include or not to include James Harris <james.harris.1@gmail.com> - 2016-09-23 13:52 +0100
        Re: To include or not to include Richard Heathfield <rjh@cpax.org.uk> - 2016-09-23 14:35 +0100
      Re: To include or not to include Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-23 18:55 +0100
        Re: To include or not to include Richard Heathfield <rjh@cpax.org.uk> - 2016-09-23 20:33 +0100
    Re: To include or not to include Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2016-09-23 08:22 -0600
    Re: To include or not to include Richard Damon <Richard@Damon-Family.org> - 2016-09-23 11:37 -0400

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


#94209

FromIke Naar <ike@iceland.freeshell.org>
Date2016-09-28 19:13 +0000
Message-ID<slrn3vfsnuo5j4.1ke.ike@iceland.freeshell.org>
In reply to#94166
On 2016-09-27, Malcolm McLean <malcolm.mclean5@btinternet.com> wrote:
> Let's say we define a structure, UFT8FILE. Essentially a file pointer, 
> but specialised to read UTF-8 streams. Now let's say we write one
> .c file, UTF8_sys.c, that defines uft8_open() and utf8_close(), We

Are the names UFT8FILE and uft8_open meant to be Malcolmisms to
lead everybody astray, or are they just typos for UTF8FILE and
utf8_open?

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


#94161

Fromsupercat@casperkitty.com
Date2016-09-27 12:38 -0700
Message-ID<8a2e45c7-0720-48dc-a088-257a9d50d513@googlegroups.com>
In reply to#94159
On Tuesday, September 27, 2016 at 1:58:03 PM UTC-5, Bart wrote:
> A 'module' corresponds more to an individual file as given to a 
> compiler, but also encompassing everything needed to define the module, 
> and without needing to half-compile it first.

Perhaps more importantly, a "module" might not bear any association with
any file processed by a C compiler, since even if its functions are called
from within C code they might be written in some other language.  Such
things are not "translation units" as the C Standard defines the term,
since it only recognizes the concept of source files being written in C.

BTW, the importation of definitions from other languages poses some other
questions that the C Standard ignores, e.g. whether a compiler can assume
that outside symbols abide by the same restrictions that would be applicable
to C code.  For example, given:

    volatile int x,y;
    int foo(void) { return &x == &y; }

would a compiler be entitled to have "foo" unconditionally return 0, or
should it have to allow for the possibility that the symbols might have
been assigned matching values somehow?  I would think that a quality
implementation on any platform where matching symbols could be created by
any means should recognize that the symbols might match, but I don't think
anything in the Standard offers any recommendations in that regard.

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


#94162

FromJames Harris <james.harris.1@gmail.com>
Date2016-09-27 20:57 +0100
Message-ID<nseiv3$k2k$1@dont-email.me>
In reply to#94158
On 27/09/2016 19:42, Keith Thompson wrote:

...

> Let me ask directly: What exactly do you mean by the word "module"?  If
> it's a synonym for "translation unit" or "source file", can you just use
> that term instead?

Not speaking for Bart but I tend to use the term 'module' in a 
conceptual sense, not something specific to C. To me, a module is a 
subdivision of a program, especially where the subdivided part is 
reusable, i.e. could be used in other programs, or is loosely tied to 
other modules.

In C such a module could be realised simply as a .c file and an 
associated .h file. Or it could be a number of source files that work 
together.

It looks as though Bart has a similar definition.

-- 
James Harris

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


#94142

Fromsupercat@casperkitty.com
Date2016-09-27 07:25 -0700
Message-ID<d3af52a4-7d8b-4899-8c8d-263af700d1b8@googlegroups.com>
In reply to#94136
On Tuesday, September 27, 2016 at 8:27:29 AM UTC-5, Ben Bacarisse wrote:
> supercat writes:
> > > Not all linkers can handle that, and there is no good reason the language
> > should not be usable on linkers that cannot.
> 
> You know that C is usable with such linkers, yes?  As you say, there is
> no good reason to prevent C being used on such systems, so the standard
> does *not* prevent C from being used on them.

I don't know that any of the implementations of C which are usable with
such linkers are fully conforming, at least when so used.  Of course, it's
possible for an implementation which is fully conforming to be incapable
of running any useful programs, or for an implementation which is not quite
fully conforming to be extremely useful, some people are averse to the idea
of a non-conforming implementation.
 

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


#94177

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-09-28 00:28 +0100
Message-ID<87wphwapnq.fsf@bsb.me.uk>
In reply to#94142
supercat@casperkitty.com writes:

> On Tuesday, September 27, 2016 at 8:27:29 AM UTC-5, Ben Bacarisse wrote:
>> supercat writes:
>> > > Not all linkers can handle that, and there is no good reason the language
>> > should not be usable on linkers that cannot.
>> 
>> You know that C is usable with such linkers, yes?  As you say, there is
>> no good reason to prevent C being used on such systems, so the standard
>> does *not* prevent C from being used on them.
>
> I don't know that any of the implementations of C which are usable with
> such linkers are fully conforming, at least when so used.

Why don't you know that?  It seems easy to know simply by looking at
what the standard says.  Have I missed your point?

<snip>
-- 
Ben.

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


#94300

Fromsupercat@casperkitty.com
Date2016-09-30 07:53 -0700
Message-ID<a1a58205-8f5a-411a-9885-dcbdfba7636f@googlegroups.com>
In reply to#94177
On Tuesday, September 27, 2016 at 6:28:32 PM UTC-5, Ben Bacarisse wrote:
> supercat writes:
> > I don't know that any of the implementations of C which are usable with
> > such linkers are fully conforming, at least when so used.
> 
> Why don't you know that?  It seems easy to know simply by looking at
> what the standard says.  Have I missed your point?

There exist linkers that characterize every global symbol reference as either
an import or an export, and require that every symbol which is imported at
least once must be exported precisely once.

According to the C Standard, by my understanding, if two source files each
include the definition "int foo;" without initialization, the result must
be the creation of one variable "foo" which is used by both source files.
The only way the aforementioned linkers could create that behavior, however,
would be to have one file export the definition and the other one import it,
which would in turn require that whatever is generating the file know which
symbols should or should not be exported.

The compilers I've seen for such linkers resolve the issue by saying that a
variable that appears in a top-level declaration without an "extern" is
exported, and one that only appears with "extern" qualifiers is imported.
It might be possible to design a utility which, given a collection of object
files, would produce a new set of object which changed all but one of the
exports for any given symbol to imports, and which could thus be linked, but
I don't think I've heard of any utility being written to work around linker
restrictions in such fashion.

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


#94304

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-09-30 16:06 +0100
Message-ID<8737kh8m13.fsf@bsb.me.uk>
In reply to#94300
supercat@casperkitty.com writes:

> On Tuesday, September 27, 2016 at 6:28:32 PM UTC-5, Ben Bacarisse wrote:
>> supercat writes:
>> > I don't know that any of the implementations of C which are usable with
>> > such linkers are fully conforming, at least when so used.
>> 
>> Why don't you know that?  It seems easy to know simply by looking at
>> what the standard says.  Have I missed your point?
>
> There exist linkers that characterize every global symbol reference as either
> an import or an export, and require that every symbol which is imported at
> least once must be exported precisely once.
>
> According to the C Standard, by my understanding, if two source files each
> include the definition "int foo;" without initialization, the result must
> be the creation of one variable "foo" which is used by both source
> files.

No, that wrong.

<snip>
-- 
Ben.

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


#94132

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-09-27 13:53 +0100
Message-ID<8737klcxma.fsf@bsb.me.uk>
In reply to#94114
James Harris <james.harris.1@gmail.com> writes:

> On 26/09/2016 17:55, BartC wrote:
>> On 26/09/2016 00:18, James Harris wrote:
>>> On 25/09/2016 15:15, BartC wrote:
>>
>>>> So it seems superfluous. Unless, for some bizarre reason, you want to
>>>> actually declare a file-scope name inside a function.
>>>
>>> IIRC this goes back to support for single pass. Consider this code:
>>>
>>>   int x = 1;
>>>   int f(void) {
>>>     return x;
>>>   }
>>>
>>> When the compiler gets to see x in the function it knows its type.
>>
>> Presumably single passes are still used because C still has trouble with
>> references to functions and variables that occur later on. (Or more
>> likely, it has to maintain that behaviour even though forward
>> declaration requirements could easily be relaxed.)
>
> I think what you wrote in parens is the right interpretation. This is
> about de jure not de facto!
>
>>>> And it doesn't really explain however why 'extern' needs to be used for
>>>> names of file-scope objects and functions that are shared between
>>>> modules.
>>>
>>> From memory I think this is a subtle difference between declarations
>>> (i.e. setting type information) and definitions (reserving storage).
>>> Consider at file scope
>>>
>>>   int x;
>>>
>>> Even though that does not assign a value, IIRC the compiler might treat
>>> it as a definition (rules as to when are fiddly). But compare that with
>>>
>>>   extern int x;
>>>
>>> The compiler will always see that as a declaration (again, with very
>>> fiddly rules) and not a definition.
>>
>> All C compilers I've tried have no problem with:
>>
>>     int x;
>>     int x;
>>     int x;
>>     int x;
>>     int x;
>>
>> within the same module, provided only one is initialised.
>>
>> Even when some of these are in other modules: the linker sees multiple
>> instances and creates only one. EXCEPT when I use Tiny C, then it will
>> report multiple definitions of x. That can be fixed by using extern in
>> all either modules except one or even when extern is used everywhere.
>>
>> I don't know if that's a problem with Tiny C, or if it's all the other
>> compilers that are being lax.
>
> I've been reading the standard's /linkage/ section again. It seems to
> be saying that certain identifiers with the same name are merged into
> one (if you like, "linked" together):

You've got to be careful when rewording things.  Aj you same, it's the
names that are "merged", but the word "merged" might suggest (as you go
on to say explicitly) that the objects so named are also merged.  That's
not the case.  The effect of external linkage applied only to the
*declarations* of the names.  (Of course, all definitions are also
declarations but not vice-versa.)

> Identifiers with external linkage are merged into one across all the
> translation units that make up a program.

Yes, provided you make it clear that this applies to the declarations.
The definitions of the objects are not merged.

> Identifiers with internal linkage are merged into one within a single
> translation unit.

That's correct, but what gives an identifier internal linkage?  Some
people will say "static" and then misunderstand you.  Only identifiers
declared at file-scope can be given internal linkage, so static objects
declared in different functions in the same translation unit are not
"merged" because they don't have internal linkage (despite the static
storage class specifier).

> And identifiers with no linkage are not merged. Each one refers to a
> separate entity.
>
> Your "int x" declarations, above, will be external if they are
> declared outside of any function so I think it's correct that they all
> be merged into one.

No.  They are all declarations, so the names get "merged", but they are
also definitions (albeit tentative ones) and there must be no more than
one definition of any object (see 6.9).

>>> Oversimplification: Maybe extern declares without reserving storage,
>>> even at file scope.
>>
>> But as I said, you can use only extern, and it will still reserve
>> storage.

If there is no definition of an object there will be no such object.  of
course, the behaviour is undefined if the program goes on to use the
object so named which means an implementation is permitted to do what it
likes, including reserving storage for the undefined object, but that
would be odd (and I'd really want to be able to turn that off in order
to see the problem!).

> What I wrote could still be correct, i.e. if the linker reserves the
> storage rather than the compiler doing so.



-- 
Ben.

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


#94319

FromJames Harris <james.harris.1@gmail.com>
Date2016-09-30 19:46 +0100
Message-ID<nsmbtk$lr$1@dont-email.me>
In reply to#94132
On 27/09/2016 13:53, Ben Bacarisse wrote:
> James Harris <james.harris.1@gmail.com> writes:
>
>> On 26/09/2016 17:55, BartC wrote:
>>> On 26/09/2016 00:18, James Harris wrote:
>>>> On 25/09/2016 15:15, BartC wrote:
>>>
>>>>> So it seems superfluous. Unless, for some bizarre reason, you want to
>>>>> actually declare a file-scope name inside a function.
>>>>
>>>> IIRC this goes back to support for single pass. Consider this code:
>>>>
>>>>   int x = 1;
>>>>   int f(void) {
>>>>     return x;
>>>>   }
>>>>
>>>> When the compiler gets to see x in the function it knows its type.
>>>
>>> Presumably single passes are still used because C still has trouble with
>>> references to functions and variables that occur later on. (Or more
>>> likely, it has to maintain that behaviour even though forward
>>> declaration requirements could easily be relaxed.)
>>
>> I think what you wrote in parens is the right interpretation. This is
>> about de jure not de facto!
>>
>>>>> And it doesn't really explain however why 'extern' needs to be used for
>>>>> names of file-scope objects and functions that are shared between
>>>>> modules.
>>>>
>>>> From memory I think this is a subtle difference between declarations
>>>> (i.e. setting type information) and definitions (reserving storage).
>>>> Consider at file scope
>>>>
>>>>   int x;
>>>>
>>>> Even though that does not assign a value, IIRC the compiler might treat
>>>> it as a definition (rules as to when are fiddly). But compare that with
>>>>
>>>>   extern int x;
>>>>
>>>> The compiler will always see that as a declaration (again, with very
>>>> fiddly rules) and not a definition.
>>>
>>> All C compilers I've tried have no problem with:
>>>
>>>     int x;
>>>     int x;
>>>     int x;
>>>     int x;
>>>     int x;
>>>
>>> within the same module, provided only one is initialised.
>>>
>>> Even when some of these are in other modules: the linker sees multiple
>>> instances and creates only one. EXCEPT when I use Tiny C, then it will
>>> report multiple definitions of x. That can be fixed by using extern in
>>> all either modules except one or even when extern is used everywhere.
>>>
>>> I don't know if that's a problem with Tiny C, or if it's all the other
>>> compilers that are being lax.
>>
>> I've been reading the standard's /linkage/ section again. It seems to
>> be saying that certain identifiers with the same name are merged into
>> one (if you like, "linked" together):
>
> You've got to be careful when rewording things.  Aj you same, it's the
> names that are "merged", but the word "merged" might suggest (as you go
> on to say explicitly) that the objects so named are also merged.  That's
> not the case.  The effect of external linkage applied only to the
> *declarations* of the names.  (Of course, all definitions are also
> declarations but not vice-versa.)

I /was/ thinking that external linkage meant that the identical names 
would refer to the same object or function across translation units. And 
that internal linkage meant the same within a translation unit. If I 
read you correctly you are saying that that is wrong but I don't 
understand why.

 From n1570:

"In the set of translation units and libraries that constitutes an 
entire program, each declaration of a particular identifier with 
external linkage denotes the same object or function."

At file scope:

   file1.c
     int x;
     int x;

   file2.c
     int x;
     int x;

I thought that that would result in one variable called x for the entire 
program.


>> Identifiers with external linkage are merged into one across all the
>> translation units that make up a program.
>
> Yes, provided you make it clear that this applies to the declarations.
> The definitions of the objects are not merged.

By "declarations" do you mean the types? I could see those not being 
matched. If we had

   file3.c
     float f;

   file4.c
     FILE *f;

I wouldn't have thought that compiler or linker would necessarily spot 
the mismatch - hence the need for headers.


-- 
James Harris

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


#94324

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-09-30 20:27 +0100
Message-ID<87wpht6vcy.fsf@bsb.me.uk>
In reply to#94319
James Harris <james.harris.1@gmail.com> writes:
<snip>
> I /was/ thinking that external linkage meant that the identical names
> would refer to the same object or function across translation
> units. And that internal linkage meant the same within a translation
> unit. If I read you correctly you are saying that that is wrong but I
> don't understand why.
>
> From n1570:
>
> "In the set of translation units and libraries that constitutes an
> entire program, each declaration of a particular identifier with
> external linkage denotes the same object or function."

Yup.  Note that it does not say each *definition* denotes the same
object -- the linkage is a property of names, not objects.

The wording is not ideal.  It's easy to read the part you quote as
suggesting the definitions be merged, but if that were the case there
would be no need for the prohibition on multiple definitions (6.9 p5).

> At file scope:
>
>   file1.c
>     int x;
>     int x;
>
>   file2.c
>     int x;
>     int x;
>
> I thought that that would result in one variable called x for the
> entire program.

All of these are both declarations *and* definitions.  When you write

  extern int x;

it is *only* a declaration.  This is how you are supposed get x "here"
to refer to the same "x" as "x" in some other translation unit.

gcc (along with many other compilers) only merges definitions when they
are tentative definitions (as above) in all but one translation unit.
Try to link two or more TUs with explicit definitions and you get an
error.  tcc, on the other hand, rejects any hint of multiple definition
as in your example.

<snip>
-- 
Ben.

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


#94026

FromReinhardt Behm <rbehm@hushmail.com>
Date2016-09-25 23:27 +0800
Message-ID<ns8qcs$at2$1@dont-email.me>
In reply to#94023
AT Sunday 25 September 2016 21:06, James Harris wrote:

> On 25/09/2016 11:58, BartC wrote:
>> On 25/09/2016 11:42, Ben Bacarisse wrote:
>>> BartC <bc@freeuk.com> writes:
>>
>>>> If this is still about 'extern', then it would seem odd writing this
>>>> in A.h:
>>>>
>>>>   extern int C_shared[];
>>>>
>>>> then a bit later in A.c and so within the same translation unit:
>>>>
>>>>   int C_shared[] = {10,20,30};
>>>>
>>>> So declaring something as external, then defining the very same thing
>>>> as belonging to this module!
>>>
>>> What a joy for you.  C has the power to amaze you with some new oddity
>>> every day.
>>
>> It's not just about me. It's illogical and confusing. If I write this in
>> Nasm:
>>
>>       extern bart
>> bart:
>>
>> it says symbol 'bart' is redefined.
>>
>> I thought C was supposed to be higher level than such languages?
> 
> Some of C's rules are for compatibility.
> 
> Besides, are you interpreting the extern keyword incorrectly. It does
> not mean what it does in Nasm. IIRC it does not mean "external to this
> translation unit".
> 
> Wouldn't it be more accurate to say that it means "external to a
> function"?
> 
> 
>> The C method does solve one problem (having a single form of declaration
>> that works in both exporting and importing modules, rather than needing
>> two), but it is not satisfactory.
> 
> I think the issue is that extern declarations are often placed in header
> files. It is convenient for the same headers to be #included in the
> clients as well as the provider.
> 
> For example, imagine you had a program fred.c with a fred.h header and
> fred.c had a global (i.e. exported) symbol mary. Then, fred.h would have
> 
>    extern int mary ....
> 
> That header is also #included in fred.c so the compiler could see
> 
>    int mary ....
>    extern int mary ....
> 
> C allows them both to appear in the same TU. Perhaps at the file level
> extern could be seen as a sort of tentative declaration....?

extern simply says that this variable is declared _somewhere_ and tells the 
compiler what type it has. It can be in the same TU or in some other.
By including the "extern int mary" via a header file also into the TU that 
declares mary and creates space for it, you make sure that at least the 
types are correct.

-- 
Reinhardt

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


#94029

FromJerry Stuckle <jstucklex@attglobal.net>
Date2016-09-25 11:38 -0400
Message-ID<ns8r1d$d7m$1@jstuckle.eternal-september.org>
In reply to#94026
On 9/25/2016 11:27 AM, Reinhardt Behm wrote:
> AT Sunday 25 September 2016 21:06, James Harris wrote:
> 
>> On 25/09/2016 11:58, BartC wrote:
>>> On 25/09/2016 11:42, Ben Bacarisse wrote:
>>>> BartC <bc@freeuk.com> writes:
>>>
>>>>> If this is still about 'extern', then it would seem odd writing this
>>>>> in A.h:
>>>>>
>>>>>   extern int C_shared[];
>>>>>
>>>>> then a bit later in A.c and so within the same translation unit:
>>>>>
>>>>>   int C_shared[] = {10,20,30};
>>>>>
>>>>> So declaring something as external, then defining the very same thing
>>>>> as belonging to this module!
>>>>
>>>> What a joy for you.  C has the power to amaze you with some new oddity
>>>> every day.
>>>
>>> It's not just about me. It's illogical and confusing. If I write this in
>>> Nasm:
>>>
>>>       extern bart
>>> bart:
>>>
>>> it says symbol 'bart' is redefined.
>>>
>>> I thought C was supposed to be higher level than such languages?
>>
>> Some of C's rules are for compatibility.
>>
>> Besides, are you interpreting the extern keyword incorrectly. It does
>> not mean what it does in Nasm. IIRC it does not mean "external to this
>> translation unit".
>>
>> Wouldn't it be more accurate to say that it means "external to a
>> function"?
>>
>>
>>> The C method does solve one problem (having a single form of declaration
>>> that works in both exporting and importing modules, rather than needing
>>> two), but it is not satisfactory.
>>
>> I think the issue is that extern declarations are often placed in header
>> files. It is convenient for the same headers to be #included in the
>> clients as well as the provider.
>>
>> For example, imagine you had a program fred.c with a fred.h header and
>> fred.c had a global (i.e. exported) symbol mary. Then, fred.h would have
>>
>>    extern int mary ....
>>
>> That header is also #included in fred.c so the compiler could see
>>
>>    int mary ....
>>    extern int mary ....
>>
>> C allows them both to appear in the same TU. Perhaps at the file level
>> extern could be seen as a sort of tentative declaration....?
> 
> extern simply says that this variable is declared _somewhere_ and tells the 
> compiler what type it has. It can be in the same TU or in some other.
> By including the "extern int mary" via a header file also into the TU that 
> declares mary and creates space for it, you make sure that at least the 
> types are correct.
> 

One correction.  extern simply says that this variable is *defined*
_somewhere_.  extern int mary would be a declaration.

A declaration identifies a variable name and type.  A definition
reserves memory for it.  A variable can be declared as many times as you
want (as long as the declarations match).  But it can only be defined
once.  Many compilers/linkers will barf if they see multiple definitions
for a variable.

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

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


#94030

FromReinhardt Behm <rbehm@hushmail.com>
Date2016-09-25 23:40 +0800
Message-ID<ns8r52$c3b$3@dont-email.me>
In reply to#94029
AT Sunday 25 September 2016 23:38, Jerry Stuckle wrote:

> On 9/25/2016 11:27 AM, Reinhardt Behm wrote:
>> AT Sunday 25 September 2016 21:06, James Harris wrote:
>> 
>>> On 25/09/2016 11:58, BartC wrote:
>>>> On 25/09/2016 11:42, Ben Bacarisse wrote:
>>>>> BartC <bc@freeuk.com> writes:
>>>>
>>>>>> If this is still about 'extern', then it would seem odd writing this
>>>>>> in A.h:
>>>>>>
>>>>>>   extern int C_shared[];
>>>>>>
>>>>>> then a bit later in A.c and so within the same translation unit:
>>>>>>
>>>>>>   int C_shared[] = {10,20,30};
>>>>>>
>>>>>> So declaring something as external, then defining the very same thing
>>>>>> as belonging to this module!
>>>>>
>>>>> What a joy for you.  C has the power to amaze you with some new oddity
>>>>> every day.
>>>>
>>>> It's not just about me. It's illogical and confusing. If I write this
>>>> in Nasm:
>>>>
>>>>       extern bart
>>>> bart:
>>>>
>>>> it says symbol 'bart' is redefined.
>>>>
>>>> I thought C was supposed to be higher level than such languages?
>>>
>>> Some of C's rules are for compatibility.
>>>
>>> Besides, are you interpreting the extern keyword incorrectly. It does
>>> not mean what it does in Nasm. IIRC it does not mean "external to this
>>> translation unit".
>>>
>>> Wouldn't it be more accurate to say that it means "external to a
>>> function"?
>>>
>>>
>>>> The C method does solve one problem (having a single form of
>>>> declaration that works in both exporting and importing modules, rather
>>>> than needing two), but it is not satisfactory.
>>>
>>> I think the issue is that extern declarations are often placed in header
>>> files. It is convenient for the same headers to be #included in the
>>> clients as well as the provider.
>>>
>>> For example, imagine you had a program fred.c with a fred.h header and
>>> fred.c had a global (i.e. exported) symbol mary. Then, fred.h would have
>>>
>>>    extern int mary ....
>>>
>>> That header is also #included in fred.c so the compiler could see
>>>
>>>    int mary ....
>>>    extern int mary ....
>>>
>>> C allows them both to appear in the same TU. Perhaps at the file level
>>> extern could be seen as a sort of tentative declaration....?
>> 
>> extern simply says that this variable is declared _somewhere_ and tells
>> the compiler what type it has. It can be in the same TU or in some other.
>> By including the "extern int mary" via a header file also into the TU
>> that declares mary and creates space for it, you make sure that at least
>> the types are correct.
>> 
> 
> One correction.  extern simply says that this variable is *defined*
> _somewhere_.  extern int mary would be a declaration.
> 
> A declaration identifies a variable name and type.  A definition
> reserves memory for it.  A variable can be declared as many times as you
> want (as long as the declarations match).  But it can only be defined
> once.  Many compilers/linkers will barf if they see multiple definitions
> for a variable.

Yes, when writing this I was thinking if i got these two terms right or not.

-- 
Reinhardt

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


#94024

FromBartC <bc@freeuk.com>
Date2016-09-25 15:06 +0100
Message-ID<ns8lku$r18$1@dont-email.me>
In reply to#94017
On 25/09/2016 11:42, Ben Bacarisse wrote:
> BartC <bc@freeuk.com> writes:

>> I hardly ever use it [extern], and rarely
>> see it used elsewhere.
>
> I'd hope not.  After decades of education, I would hope that programs
> that rely on "global" data objects are getting increasingly rare.

But global functions, global typedefs, global struct tags, global enum 
names, global #defines and global #includes (ie. module names) are still 
acceptable? It could get tricky otherwise.

What about file-scope data objects; are they also frowned upon?

Meanwhile with a language that really has banned globals you get 
yourself tied up in knots trying to create one.

-- 
Bartc

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


#94032

FromJerry Stuckle <jstucklex@attglobal.net>
Date2016-09-25 11:49 -0400
Message-ID<ns8rln$f99$1@jstuckle.eternal-september.org>
In reply to#94024
On 9/25/2016 10:06 AM, BartC wrote:
> On 25/09/2016 11:42, Ben Bacarisse wrote:
>> BartC <bc@freeuk.com> writes:
> 
>>> I hardly ever use it [extern], and rarely
>>> see it used elsewhere.
>>
>> I'd hope not.  After decades of education, I would hope that programs
>> that rely on "global" data objects are getting increasingly rare.
> 
> But global functions, global typedefs, global struct tags, global enum
> names, global #defines and global #includes (ie. module names) are still
> acceptable? It could get tricky otherwise.
> 
> What about file-scope data objects; are they also frowned upon?
> 
> Meanwhile with a language that really has banned globals you get
> yourself tied up in knots trying to create one.
> 

A big difference between a global variable and global functions,
typedefs, etc.

The main reason to avoid global variables is simple - program
reliability.  Let's say you have a global "foo" of type int.  Valid
values are between 0 and 10.

At one point in your program, you find it occasionally gets a value like
423910863407.  How did it get there?

If it's a global variable, that could have happened anywhere in the
program.  What if your program is 500K lines long?

File scope is better, because only functions in the file can access the
variable (barring, of course, memory corruption).  That at least limits
the impact.

Not having a global at all limits access to functions where the variable
is passed (and then you can insert debugging code to locate the invalid
change).

With that said, sometimes you still need to use globals, especially in
kernel programming when using multiple threads.

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

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


#94037

FromBartC <bc@freeuk.com>
Date2016-09-25 18:05 +0100
Message-ID<ns904g$eb$1@dont-email.me>
In reply to#94032
On 25/09/2016 16:49, Jerry Stuckle wrote:
> On 9/25/2016 10:06 AM, BartC wrote:

>> But global functions, global typedefs, global struct tags, global enum
>> names, global #defines and global #includes (ie. module names) are still
>> acceptable? It could get tricky otherwise.
>>
>> What about file-scope data objects; are they also frowned upon?

> A big difference between a global variable and global functions,
> typedefs, etc.
>
> The main reason to avoid global variables is simple - program
> reliability.  Let's say you have a global "foo" of type int.  Valid
> values are between 0 and 10.
>
> At one point in your program, you find it occasionally gets a value like
> 423910863407.  How did it get there?

Maybe someone defined a file-scope variable and forgot to stick 'static' 
in front?

But what about globals that have 'const' in front (such as large 
read-only tables); they will be protected surely?

And of course if you have a function F() shared between modules A and B, 
nothing stops module X from calling it.

> If it's a global variable, that could have happened anywhere in the
> program.  What if your program is 500K lines long?
>
> File scope is better, because only functions in the file can access the
> variable (barring, of course, memory corruption).  That at least limits
> the impact.

Suppose you need to split one module into two. Then you will need start 
using globals to share file-scope variables between the two.

> With that said, sometimes you still need to use globals, especially in
> kernel programming when using multiple threads.

Everyone can find their own examples where they are indispensable.

-- 
Bartc

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


#94047

FromJerry Stuckle <jstucklex@attglobal.net>
Date2016-09-25 16:42 -0400
Message-ID<ns9cr6$g05$1@jstuckle.eternal-september.org>
In reply to#94037
On 9/25/2016 1:05 PM, BartC wrote:
> On 25/09/2016 16:49, Jerry Stuckle wrote:
>> On 9/25/2016 10:06 AM, BartC wrote:
> 
>>> But global functions, global typedefs, global struct tags, global enum
>>> names, global #defines and global #includes (ie. module names) are still
>>> acceptable? It could get tricky otherwise.
>>>
>>> What about file-scope data objects; are they also frowned upon?
> 
>> A big difference between a global variable and global functions,
>> typedefs, etc.
>>
>> The main reason to avoid global variables is simple - program
>> reliability.  Let's say you have a global "foo" of type int.  Valid
>> values are between 0 and 10.
>>
>> At one point in your program, you find it occasionally gets a value like
>> 423910863407.  How did it get there?
> 
> Maybe someone defined a file-scope variable and forgot to stick 'static'
> in front?
>

Or, maybe it was just plain sloppy programming - using globals when one
shouldn't.

> But what about globals that have 'const' in front (such as large
> read-only tables); they will be protected surely?
> 

Nope.  const is not necessarily enforced in C, like it is in C++.  And
even if it were, how could you change it when you need to?

> And of course if you have a function F() shared between modules A and B,
> nothing stops module X from calling it.
> 

Which has nothing to do with a global variable.

>> If it's a global variable, that could have happened anywhere in the
>> program.  What if your program is 500K lines long?
>>
>> File scope is better, because only functions in the file can access the
>> variable (barring, of course, memory corruption).  That at least limits
>> the impact.
> 
> Suppose you need to split one module into two. Then you will need start
> using globals to share file-scope variables between the two.
> 

Nope.  Pass variables as parameters, as necessary.

>> With that said, sometimes you still need to use globals, especially in
>> kernel programming when using multiple threads.
> 
> Everyone can find their own examples where they are indispensable.
> 

Yes, everyone can make excuses for misusing them.  Good programmers know
how to use them *only when they are needed*.  Bad programmers make
excuses for using them.

User applications almost never need global variables.

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

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


#94050

FromBartC <bc@freeuk.com>
Date2016-09-25 21:53 +0100
Message-ID<ns9dg0$i9m$1@dont-email.me>
In reply to#94047
On 25/09/2016 21:42, Jerry Stuckle wrote:
> On 9/25/2016 1:05 PM, BartC wrote:

>> And of course if you have a function F() shared between modules A and B,
>> nothing stops module X from calling it.
>>
>
> Which has nothing to do with a global variable.

> User applications almost never need global variables.

But they have global functions instead which can do the same job. 
Suppose F() maintains an object shared between A and B; X can call F() 
and make changes just as it could directly write to the object if it was 
global.

-- 
Bartc

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


#94057

FromJerry Stuckle <jstucklex@attglobal.net>
Date2016-09-25 17:57 -0400
Message-ID<ns9h8b$u48$1@jstuckle.eternal-september.org>
In reply to#94050
On 9/25/2016 4:53 PM, BartC wrote:
> On 25/09/2016 21:42, Jerry Stuckle wrote:
>> On 9/25/2016 1:05 PM, BartC wrote:
> 
>>> And of course if you have a function F() shared between modules A and B,
>>> nothing stops module X from calling it.
>>>
>>
>> Which has nothing to do with a global variable.
> 
>> User applications almost never need global variables.
> 
> But they have global functions instead which can do the same job.
> Suppose F() maintains an object shared between A and B; X can call F()
> and make changes just as it could directly write to the object if it was
> global.
> 

Global functions are not the same as global variables.  And sure, F()
could make changes to the object.  But it can also ensure the changes
are valid before doing so.

No such protection is possible with global variables.

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

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


#94046

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-09-25 21:20 +0100
Message-ID<87fuonenoc.fsf@bsb.me.uk>
In reply to#94024
BartC <bc@freeuk.com> writes:

> On 25/09/2016 11:42, Ben Bacarisse wrote:
>> BartC <bc@freeuk.com> writes:
>
>>> I hardly ever use it [extern], and rarely
>>> see it used elsewhere.
>>
>> I'd hope not.  After decades of education, I would hope that programs
>> that rely on "global" data objects are getting increasingly rare.
>
> But global functions, global typedefs, global struct tags, global enum
> names, global #defines and global #includes (ie. module names) are
> still acceptable? It could get tricky otherwise.

I'm not sure I know what all these are.  I used the term "global"
because I wanted to relate C to the developments in programming style
that have been evolving for 60 years or so.  And I used scare quotes
because "global" is not properly defined in C.

The real problem objects are the ones you alluded to in your post:
non-const objects declared (in an included header file) at file scope
with external linkage.

> What about file-scope data objects; are they also frowned upon?

It depends on the linkage.

Non-const objects declared at file scope with external linkage are the
ones everyone should try to avoid.  But some people urge limiting the
scope of names as much as is reasonable, and in that context, objects
declared at file scope with *internal* linkage are also a worry for
readability.  How deep a frown they provoke depends very much on the
context and the complexity of trying to work round having them.

> Meanwhile with a language that really has banned globals you get
> yourself tied up in knots trying to create one.

I don't know what that means.

-- 
Ben.

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


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

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


csiph-web