Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #93934 > unrolled thread
| Started by | James Harris <james.harris.1@gmail.com> |
|---|---|
| First post | 2016-09-23 10:45 +0100 |
| Last post | 2016-09-23 11:37 -0400 |
| Articles | 20 on this page of 70 — 16 participants |
Back to article view | Back to comp.lang.c
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 →
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | James Harris <james.harris.1@gmail.com> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2016-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2016-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2016-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