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 3 of 4 — ← Prev page 1 2 [3] 4 Next page →
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | James Harris <james.harris.1@gmail.com> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-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]
| From | James Harris <james.harris.1@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-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]
| From | Reinhardt Behm <rbehm@hushmail.com> |
|---|---|
| Date | 2016-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]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2016-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]
| From | Reinhardt Behm <rbehm@hushmail.com> |
|---|---|
| Date | 2016-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-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]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2016-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-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]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2016-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-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]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2016-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-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