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 2 of 4 — ← Prev page 1 [2] 3 4  Next page →


#94100

Fromsupercat@casperkitty.com
Date2016-09-26 12:13 -0700
Message-ID<196eb6e0-bd76-4634-acb8-e8da858dd37d@googlegroups.com>
In reply to#94095
On Monday, September 26, 2016 at 11:55:47 AM UTC-5, Bart wrote:
> 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.

The author of a C compiler may not have any control over a system's linking
process.  Some systems allow for "weak" definitions, while others do not.
If a compiler is being used with a linker which requires that every symbol
that is referenced anywhere must have have exactly one definition, that
requirement is going to make it necessary to tell the compiler to export
each symbol in exactly one translation unit.

Given the requirement that each symbol be exported exactly once, I think it
would have been easier for C to say that a top-level definition which does
not have either "extern" or "static" will export a symbol, regardless of
whether an initializer is given, and allow for any number of extern or
static declarations, with or without initializers, none of which will
export symbols, provided all of them are consistent with each other and with
the exported definition, if any.  That would have made the compiler design
simpler, and allowed constructs like 

  #ifndef FOO_C 
  extern
  #endif
  unsigned char foo_dat[] = {1,2,3,4,5, ... };

to be included within a header file, making the complete type of foo_dat
available to client code.  C doesn't work that way, however.

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


#94114

FromJames Harris <james.harris.1@gmail.com>
Date2016-09-27 01:25 +0100
Message-ID<nscea2$3fk$1@dont-email.me>
In reply to#94095
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):

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

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

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.

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

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


-- 
James Harris

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


#94120

Fromsupercat@casperkitty.com
Date2016-09-26 18:05 -0700
Message-ID<d7eb853d-1327-47e3-b3fc-f88cf9697454@googlegroups.com>
In reply to#94114
On Monday, September 26, 2016 at 7:25:56 PM UTC-5, James Harris wrote:
> 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):
> 
> Identifiers with external linkage are merged into one across all the 
> translation units that make up a program.

Not all linkers can handle that, and there is no good reason the language
should not be usable on linkers that cannot.

An approach which is vastly more useful than throwing up one's hands in
despair and saying that platforms with primitive linkers can't run C is
to say that exactly one translation unit must have a declaration which
is not qualified "extern".

Actually, I'd posit that having a linker insist that each object which
is not qualified as "weak" must have exactly one definition would be a
useful behavior, since the alternative would generally be to have the
linker accept without complaint a combination of compilation units that
accidentally use variables with the same name for different purposes.
While weak declarations are sometimes useful, they should be explicitly
requested, rather than a default behavior.

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


#94136

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-09-27 14:27 +0100
Message-ID<87vaxhbhhi.fsf@bsb.me.uk>
In reply to#94120
supercat@casperkitty.com writes:

> On Monday, September 26, 2016 at 7:25:56 PM UTC-5, James Harris wrote:
>> 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):
>> 
>> Identifiers with external linkage are merged into one across all the 
>> translation units that make up a program.
>
> 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.

> An approach which is vastly more useful than throwing up one's hands in
> despair and saying that platforms with primitive linkers can't run C is
> to say that exactly one translation unit must have a declaration which
> is not qualified "extern".

The actual rule used by C is that if a declared function or object is
actually used, there must be exactly one definition of it.  I think it's
a neater way of putting it.

<snip>
-- 
Ben.

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


#94138

FromBartC <bc@freeuk.com>
Date2016-09-27 14:49 +0100
Message-ID<nsdtc9$vpr$1@dont-email.me>
In reply to#94136
On 27/09/2016 14:27, Ben Bacarisse wrote:
> supercat@casperkitty.com writes:
>
>> On Monday, September 26, 2016 at 7:25:56 PM UTC-5, James Harris wrote:
>>> 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):
>>>
>>> Identifiers with external linkage are merged into one across all the
>>> translation units that make up a program.
>>
>> 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.
>
>> An approach which is vastly more useful than throwing up one's hands in
>> despair and saying that platforms with primitive linkers can't run C is
>> to say that exactly one translation unit must have a declaration which
>> is not qualified "extern".
>
> The actual rule used by C is that if a declared function or object is
> actually used, there must be exactly one definition of it.  I think it's
> a neater way of putting it.

Which leads to a problem due to the way C automatically exports objects 
unless you say 'static'.

You use a library consisting of modules X,Y which share a program-scope 
variable D.

But your own module A uses a filescope variable D as well. No error is 
given (unless you use some of your obscure options). And the program 
will go wrong.

Or it will go wrong anyway even without forgetting 'static', if you have 
modules A and B that share object D.

Of course you will say this is a problem with using such global objects. 
But the way C works and the way linkers work in not detecting duplicate 
exports (of uninitialised data) doesn't help in detecting inadvertent 
clashes of names.

-- 
Bartc

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


#94140

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-09-27 15:15 +0100
Message-ID<87inthbf8o.fsf@bsb.me.uk>
In reply to#94138
BartC <bc@freeuk.com> writes:

> On 27/09/2016 14:27, Ben Bacarisse wrote:
>> supercat@casperkitty.com writes:
>>
>>> On Monday, September 26, 2016 at 7:25:56 PM UTC-5, James Harris wrote:
>>>> 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):
>>>>
>>>> Identifiers with external linkage are merged into one across all the
>>>> translation units that make up a program.
>>>
>>> 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.
>>
>>> An approach which is vastly more useful than throwing up one's hands in
>>> despair and saying that platforms with primitive linkers can't run C is
>>> to say that exactly one translation unit must have a declaration which
>>> is not qualified "extern".
>>
>> The actual rule used by C is that if a declared function or object is
>> actually used, there must be exactly one definition of it.  I think it's
>> a neater way of putting it.
>
> Which leads to a problem due to the way C automatically exports
> objects unless you say 'static'.
>
> You use a library consisting of modules X,Y which share a
> program-scope variable D.

How do I tell that modules called X and Y are being used?  I.e. what do
you mean by this term, since has no formal definition in C?  And if I
can't tell there is a module called X, why do you bring it up?

> But your own module A uses a filescope variable D as well. No error is
> given (unless you use some of your obscure options). And the program
> will go wrong.

The option is obscure to you.  Many other people use it as a matter of
course.

But your point still stands because implementations are not required to
diagnose a duplicate definition.  That's why libraries should take great
care to document what symbols they make external and, as far as
possible, prevent clashes by using some name prefix.

> Or it will go wrong anyway even without forgetting 'static', if you
> have modules A and B that share object D.

No idea what you mean here, but it sounds plausible, although possibly
rather obvious.  Lots of things can go wrong of you forget to use
important keywords.  Is your point more subtle than that?

> Of course you will say this is a problem with using such global
> objects. But the way C works and the way linkers work in not detecting
> duplicate exports (of uninitialised data) doesn't help in detecting
> inadvertent clashes of names.

No, it's a problem with the language.  A modern language would have
name-spaces and/or a module mechanism.

You seem to think I am some kind of mad C champion, but I am not.  My
posts have been largely to do with correcting your mistakes, both when
using C and when trying to explain it in as complex a way as possible.

-- 
Ben.

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


#94144

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2016-09-27 07:42 -0700
Message-ID<9b8d8341-12b3-4f11-9bc4-4d4e712d2b00@googlegroups.com>
In reply to#94140
On Tuesday, September 27, 2016 at 3:16:01 PM UTC+1, Ben Bacarisse wrote:
> BartC <bc@freeuk.com> writes:
> 
> > On 27/09/2016 14:27, Ben Bacarisse wrote:
> 
> > Of course you will say this is a problem with using such global
> > objects. But the way C works and the way linkers work in not detecting
> > duplicate exports (of uninitialised data) doesn't help in detecting
> > inadvertent clashes of names.
> 
> No, it's a problem with the language.  A modern language would have
> name-spaces and/or a module mechanism.
> 
It's also a problem with the way C linkers and compilers usually work.
Let's say I need to duplicate a string in several areas. One way is to declare
mystrdup() a global function. But I'm writing a dungeon generator module, 
I don't want to export trivial string handling functions. So the best option is
to make mystrdup() static, and drop a copy in dungeongeneratormk1.c,
dungeongeneratormk2.c and so on.

But let's say I miss the static. Easily done.  But the compiler should warn that
mystrdup is in global scope but not in the header - generally it won't. We've
got something we can link to, but not call safely. Then everything appears to
work, until I make the same mistake again. Then it may fail, but only if I call
both generatedungeonmk1 and generatedungeonmk2 from the same program.

It's not very helpful.

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


#94154

FromKeith Thompson <kst-u@mib.org>
Date2016-09-27 09:30 -0700
Message-ID<lnwphxs3t5.fsf@kst-u.example.com>
In reply to#94144
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> On Tuesday, September 27, 2016 at 3:16:01 PM UTC+1, Ben Bacarisse wrote:
[...]
>> No, it's a problem with the language.  A modern language would have
>> name-spaces and/or a module mechanism.
>> 
> It's also a problem with the way C linkers and compilers usually work.
> Let's say I need to duplicate a string in several areas. One way is to
> declare mystrdup() a global function. But I'm writing a dungeon
> generator module, I don't want to export trivial string handling
> functions. So the best option is to make mystrdup() static, and drop a
> copy in dungeongeneratormk1.c, dungeongeneratormk2.c and so on.

No, the best option is to define mystrdup() in one place and make it
visible in other translation units.

But if you insist on making it static, you can always define it in a .c
file and #include that .c file where you need it.  You'll have multiple
definitions in your program, but only one definition in your source
code.

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


#94156

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2016-09-27 10:06 -0700
Message-ID<4d955c42-b8a4-46fd-8b48-cd0dc63bd924@googlegroups.com>
In reply to#94154
On Tuesday, September 27, 2016 at 5:30:32 PM UTC+1, Keith Thompson wrote:
> Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> > On Tuesday, September 27, 2016 at 3:16:01 PM UTC+1, Ben Bacarisse wrote:
> [...]
> >> No, it's a problem with the language.  A modern language would have
> >> name-spaces and/or a module mechanism.
> >> 
> > It's also a problem with the way C linkers and compilers usually work.
> > Let's say I need to duplicate a string in several areas. One way is to
> > declare mystrdup() a global function. But I'm writing a dungeon
> > generator module, I don't want to export trivial string handling
> > functions. So the best option is to make mystrdup() static, and drop a
> > copy in dungeongeneratormk1.c, dungeongeneratormk2.c and so on.
> 
> No, the best option is to define mystrdup() in one place and make it
> visible in other translation units.
> 
> But if you insist on making it static, you can always define it in a .c
> file and #include that .c file where you need it.  You'll have multiple
> definitions in your program, but only one definition in your source
> code.
> 
A source file is a natural unit. If it is leaf, then it's inherently reusable. If it drags
in other dependencies, it's much less reusable. Sometimes subroutines are so
complex that it's not reasonable to provide them. But you want to avoid a situation
whereby something middle-level, like generatedungeon(), will not compile
just because a string duplicating function is missing.

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


#94145

Fromsupercat@casperkitty.com
Date2016-09-27 08:12 -0700
Message-ID<638eda32-8e16-4e77-91f3-377384e7a07e@googlegroups.com>
In reply to#94140
On Tuesday, September 27, 2016 at 9:16:01 AM UTC-5, Ben Bacarisse wrote:
> No idea what you mean here, but it sounds plausible, although possibly
> rather obvious.  Lots of things can go wrong of you forget to use
> important keywords.  Is your point more subtle than that?

A useful principle in languages that are designed for writing robust code
is that to the extent practical, things which are going to fail should
either consistently with minimal dependency on other seemingly-unrelated
parts of the system, or should fail with a diagnostic prior to program
execution (possibly in ways which involve interactions with other
seemingly-unrelated parts of the system).

If a link system requires that symbols must either have exactly one
"normal" definition or else zero normal definitions at at least one "weak"
one, then naming conflicts that arise when e.g. a library is upgraded to a
newer one, will be detected prior to program execution.  If duplicate
definitions are silently merged, however, the person who upgraded the
library will not perceive any problem with the code, and the code in which
the upgraded library is used will not have had any problem, but upgrading
the library may break some unrelated part of the code that used a variable
for a different purpose.

If the Standard had recognized the existence of more than one "link model",
and recommended that implementations should when practical provide options
to select programs written to different models, but applications should
when practical be written so as to avoid being dependent on any particular
model, that would have been better than trying to pretend that there is
only one "right way" of doing things.

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


#94205

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-09-28 10:46 -0700
Message-ID<kfn60pfc3y4.fsf@x-alumni2.alumni.caltech.edu>
In reply to#94145
supercat@casperkitty.com writes:

> [..different kinds of linking behavior..]
>
> If the Standard had recognized the existence of more than one
> "link model",

The Standard does recognize the existence of more than one
link model:  that's why the semantics in such cases is
undefined behavior rather than being a constraint violation.

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


#94155

FromBartC <bc@freeuk.com>
Date2016-09-27 17:55 +0100
Message-ID<nse8am$auu$1@dont-email.me>
In reply to#94140
On 27/09/2016 15:15, Ben Bacarisse wrote:
> BartC <bc@freeuk.com> writes:

>> Which leads to a problem due to the way C automatically exports
>> objects unless you say 'static'.
>>
>> You use a library consisting of modules X,Y which share a
>> program-scope variable D.
>
> How do I tell that modules called X and Y are being used?  I.e. what do
> you mean by this term, since has no formal definition in C?

   gcc A.c X.c Y.c

But, with auto-make systems people use these days, you may not know. 
That doesn't change the point however.

   And if I
> can't tell there is a module called X, why do you bring it up?
>
>> But your own module A uses a filescope variable D as well. No error is
>> given (unless you use some of your obscure options). And the program
>> will go wrong.
>
> The option is obscure to you.  Many other people use it as a matter of
> course.

This is '-fno-common'? I have trouble using it with other compilers so 
it seems to be a gcc-ism as is not general fix.

> But your point still stands because implementations are not required to
> diagnose a duplicate definition.  That's why libraries should take great
> care to document what symbols they make external and, as far as
> possible, prevent clashes by using some name prefix.
>
>> Or it will go wrong anyway even without forgetting 'static', if you
>> have modules A and B that share object D.
>
> No idea what you mean here, but it sounds plausible, although possibly
> rather obvious.  Lots of things can go wrong of you forget to use
> important keywords.  Is your point more subtle than that?

No. Some modules in your application use a global D that happens to be 
the same name as a global used in an obscure corner of your program, 
perhaps part of some library that you know little about.

>> Of course you will say this is a problem with using such global
>> objects. But the way C works and the way linkers work in not detecting
>> duplicate exports (of uninitialised data) doesn't help in detecting
>> inadvertent clashes of names.
>
> No, it's a problem with the language.  A modern language would have
> name-spaces and/or a module mechanism.

Yes, it's a language/linker problem. But you don't need fancy modern 
features to have done something about over the last few decades.

All the languages, compilers and odd linker I've created have dealt with 
the issues more sensibly than C has.

(Step 1: make it an error to write int x,x;. It's not rocket science!)

> You seem to think I am some kind of mad C champion, but I am not.  My
> posts have been largely to do with correcting your mistakes, both when
> using C and when trying to explain it in as complex a way as possible.

Because it /is/ complex. One module has int x,x,x; another has extern 
int x,x; another has extern int x,x; int x. A mess, but somehow it works 
(unless you use gcc/ld and -fno-common, or use tcc).

Then a fourth module has double x,x,x,x; and it still compiles and 
links, but now will probably go wrong.

Which module 'owns' x, and why?

It does seem that C allows you to throw together any sort of sloppy 
declarations (to go with the mix-ups between pointers and arrays), and 
somehow manages to work - if you're lucky (by avoiding obvious mistakes 
that cannot be detected.

You may not be a champion of the language but you don't seem that 
bothered either.

-- 
Bartc

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


#94157

Fromsupercat@casperkitty.com
Date2016-09-27 10:19 -0700
Message-ID<1b927f33-0f00-478a-a3fc-4cbed91f3ec3@googlegroups.com>
In reply to#94155
On Tuesday, September 27, 2016 at 11:56:08 AM UTC-5, Bart wrote:
> (Step 1: make it an error to write int x,x;. It's not rocket science!)

Or better yet, recognize a category of constructs which implementations may
reject (with a diagnostic) but may also accept, without diagnostic, if they
can run it in a Standard-specified fashion.  The authors of the Standard
seem to view such constructs as fragmenting the language, but the lack of
them is far worse.

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


#94158

FromKeith Thompson <kst-u@mib.org>
Date2016-09-27 11:42 -0700
Message-ID<lnshslrxot.fsf@kst-u.example.com>
In reply to#94155
BartC <bc@freeuk.com> writes:
> On 27/09/2016 15:15, Ben Bacarisse wrote:
>> BartC <bc@freeuk.com> writes:
>
>>> Which leads to a problem due to the way C automatically exports
>>> objects unless you say 'static'.
>>>
>>> You use a library consisting of modules X,Y which share a
>>> program-scope variable D.
>>
>> How do I tell that modules called X and Y are being used?  I.e. what do
>> you mean by this term, since has no formal definition in C?
>
>    gcc A.c X.c Y.c

Was that intended to explain what you mean by the word "module"?

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?

> But, with auto-make systems people use these days, you may not know. 
> That doesn't change the point however.

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


#94159

FromBartC <bc@freeuk.com>
Date2016-09-27 19:57 +0100
Message-ID<nseff3$7bc$1@dont-email.me>
In reply to#94158
On 27/09/2016 19:42, Keith Thompson wrote:
> BartC <bc@freeuk.com> writes:

>>    gcc A.c X.c Y.c
>
> Was that intended to explain what you mean by the word "module"?


> Let me ask directly: What exactly do you mean by the word "module"?

The same as as 'module' means in any of dozens of languages.

> If
> it's a synonym for "translation unit" or "source file", can you just use
> that term instead?

'module' isn't exactly the same as those. A source file can comprise 
other source files via include; or it can itself be part of another.

While a 'translation unit' I guess is what you get after you submit a 
top-level source file to a compiler and it does a preprocessor pass.

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.

C being C, it naturally makes it hard to be more precise: three 
source-files A, B and C, of 500 lines each, each include the same header 
file H of 10000 lines. So most of the 'translation unit' is actually 
common between the three.

-- 
Bartc

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


#94160

FromKeith Thompson <kst-u@mib.org>
Date2016-09-27 12:38 -0700
Message-ID<lnoa39rv49.fsf@kst-u.example.com>
In reply to#94159
BartC <bc@freeuk.com> writes:
> On 27/09/2016 19:42, Keith Thompson wrote:
>> BartC <bc@freeuk.com> writes:
>
>>>    gcc A.c X.c Y.c
>>
>> Was that intended to explain what you mean by the word "module"?
>
>
>> Let me ask directly: What exactly do you mean by the word "module"?
>
> The same as as 'module' means in any of dozens of languages.

What it means in some other languages is a language-level construct
called a "module" (or a "package"), and the details can vary from one
language to another.  C has no such language-level construct.

>> If
>> it's a synonym for "translation unit" or "source file", can you just use
>> that term instead?
>
> 'module' isn't exactly the same as those. A source file can comprise 
> other source files via include; or it can itself be part of another.

A source file is just a file.  It can contain #include directives that
tell the preprocessor to open other files when processing it, but those
other files are not part of the source file.

> While a 'translation unit' I guess is what you get after you submit a 
> top-level source file to a compiler and it does a preprocessor pass.

Syntactically, a translation-unit is defined as a sequence of zero or
more external-declarations (function-definitions or declarations).

N1570 5.1.1.1 defines the various terms (using * to denote italics,
i.e., definitions):

    A C program need not all be translated at the same time. The
    text of the program is kept in units called *source files*,
    (or *preprocessing files*) in this International Standard. A
    source file together with all the headers and source files
    included via the preprocessing directive #include is known
    as a *preprocessing translation unit*. After preprocessing,
    a preprocessing translation unit is called a *translation unit*.

> 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.
>
> C being C, it naturally makes it hard to be more precise: three 
> source-files A, B and C, of 500 lines each, each include the same header 
> file H of 10000 lines. So most of the 'translation unit' is actually 
> common between the three.

Yes, most of the translation units derived from the source files A,
B, and C is derived from H.  (The version of H that's included might
not be the same if it depends on macros defined in A, B, and/or C.)

I'm still not at all clear what you mean by "module", or how it
differs from a translation unit.  The phrase "everything needed to
define the module" seems a bit circular.

Can you give an example of something that's a translation unit but
not a "module", or vice versa?  And if so, how is the concept of a
"module" useful?

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


#94164

FromBartC <bc@freeuk.com>
Date2016-09-27 21:00 +0100
Message-ID<nsej40$kr7$1@dont-email.me>
In reply to#94160
On 27/09/2016 20:38, Keith Thompson wrote:
> BartC <bc@freeuk.com> writes:

> I'm still not at all clear what you mean by "module", or how it
> differs from a translation unit.  The phrase "everything needed to
> define the module" seems a bit circular.

It really isn't that important. Sometimes you just want to break up a 
paragraph by not repeating the same term. If you want to think about it 
in turns of TUs, that's fine.

> Can you give an example of something that's a translation unit but
> not a "module", or vice versa?  And if so, how is the concept of a
> "module" useful?

It's like thinking in terms of algorithms in a language neutral manner.

You design a project as well-defined modules, then make the best fit you 
can to the implementation language.

Also, my own language does have modules proper, and they can map 
one-to-one to their C representations. (Although it doesn't work as well 
the other way as C allows chaotic structure of a program.)

-- 
Bartc

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


#94180

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-09-28 01:50 +0100
Message-ID<87r384alvd.fsf@bsb.me.uk>
In reply to#94164
BartC <bc@freeuk.com> writes:

> On 27/09/2016 20:38, Keith Thompson wrote:
<snip>
>> Can you give an example of something that's a translation unit but
>> not a "module", or vice versa?  And if so, how is the concept of a
>> "module" useful?
>
> It's like thinking in terms of algorithms in a language neutral
> manner.

But you used the term in a discussion of language specifics.  Thinking
about language specifics in language neutral manner is, er, unhelpful.

<snip>
-- 
Ben.

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


#94183

FromBartC <bc@freeuk.com>
Date2016-09-28 10:55 +0100
Message-ID<nsg429$mbt$1@dont-email.me>
In reply to#94180
On 28/09/2016 01:50, Ben Bacarisse wrote:
> BartC <bc@freeuk.com> writes:
>
>> On 27/09/2016 20:38, Keith Thompson wrote:
> <snip>
>>> Can you give an example of something that's a translation unit but
>>> not a "module", or vice versa?  And if so, how is the concept of a
>>> "module" useful?
>>
>> It's like thinking in terms of algorithms in a language neutral
>> manner.
>
> But you used the term in a discussion of language specifics.  Thinking
> about language specifics in language neutral manner is, er, unhelpful.

Language specifics to do with include files, which were used to 
implement discrete modules rather than a source code free-for-all.

Header files seem to be the main tool for implementing modules.

(There are other ways: I convert a language with modules, into C source 
files that don't use headers at all. Effectively, each source file forms 
an expanded 'translation unit' in a single file. But that is not 
practical without additional tools.)

-- 
Bartc

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


#94166

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2016-09-27 13:33 -0700
Message-ID<d07f09fb-37bf-47db-9847-89f01863dd06@googlegroups.com>
In reply to#94160
On Tuesday, September 27, 2016 at 8:38:36 PM UTC+1, Keith Thompson wrote:

> Can you give an example of something that's a translation unit but
> not a "module", or vice versa?  And if so, how is the concept of a
> "module" useful?
> 
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
then have another .c file, called UTF8_fuctions.c, that defines 
operation such as fpututf8() which operate on UTF8FILE *.

Now the division probably makes sense because to open a file likely
requires quite a bit of system-specific code. However the code to
translate from a unicode code point to UTF-8 for the fpututf8()
function can be platform independent, there's no reason to use any
non-portable code there.

But UTF8_functions.c depends on UTF*_sys.c UTF8_sys.c is your only 
way of creating an initialised UTF8FILE *. So whilst UTF8_functions.c
is a translation unit, it is not a "module". The module is the two files
together with their associated includes. 

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


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

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


csiph-web