Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #106887 > unrolled thread
| Started by | acidlategamer@gmail.com |
|---|---|
| First post | 2017-03-24 04:23 -0700 |
| Last post | 2017-03-25 12:13 -0700 |
| Articles | 20 on this page of 26 — 12 participants |
Back to article view | Back to comp.lang.c
Can a variable be both static and extern acidlategamer@gmail.com - 2017-03-24 04:23 -0700
Re: Can a variable be both static and extern Richard Heathfield <rjh@cpax.org.uk> - 2017-03-24 11:40 +0000
Re: Can a variable be both static and extern acidlategamer@gmail.com - 2017-03-24 04:54 -0700
Re: Can a variable be both static and extern Richard Heathfield <rjh@cpax.org.uk> - 2017-03-24 12:09 +0000
Re: Can a variable be both static and extern James Kuyper <jameskuyper@verizon.net> - 2017-03-24 11:45 -0400
Re: Can a variable be both static and extern raltbos@xs4all.nl (Richard Bos) - 2017-03-25 22:27 +0000
Re: Can a variable be both static and extern Keith Thompson <kst-u@mib.org> - 2017-03-24 11:35 -0700
Re: Can a variable be both static and extern Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-24 12:11 +0000
Re: Can a variable be both static and extern raltbos@xs4all.nl (Richard Bos) - 2017-03-24 12:14 +0000
Re: Can a variable be both static and extern David Brown <david.brown@hesbynett.no> - 2017-03-24 17:11 +0100
Re: Can a variable be both static and extern scott@slp53.sl.home (Scott Lurndal) - 2017-03-24 16:22 +0000
Re: Can a variable be both static and extern David Brown <david.brown@hesbynett.no> - 2017-03-24 17:38 +0100
Re: Can a variable be both static and extern James Kuyper <jameskuyper@verizon.net> - 2017-03-24 12:23 -0400
Re: Can a variable be both static and extern David Brown <david.brown@hesbynett.no> - 2017-03-24 17:41 +0100
Re: Can a variable be both static and extern jameskuyper@verizon.net - 2017-03-24 09:57 -0700
Re: Can a variable be both static and extern supercat@casperkitty.com - 2017-03-24 10:38 -0700
Re: Can a variable be both static and extern Richard Heathfield <rjh@cpax.org.uk> - 2017-03-24 18:24 +0000
Re: Can a variable be both static and extern "James R. Kuyper" <jameskuyper@verizon.net> - 2017-03-25 10:47 -0400
Re: Can a variable be both static and extern Richard Heathfield <rjh@cpax.org.uk> - 2017-03-25 16:48 +0000
Re: Can a variable be both static and extern Keith Thompson <kst-u@mib.org> - 2017-03-25 10:31 -0700
Re: Can a variable be both static and extern Richard Heathfield <rjh@cpax.org.uk> - 2017-03-25 18:23 +0000
Re: Can a variable be both static and extern supercat@casperkitty.com - 2017-03-25 12:28 -0700
Re: Can a variable be both static and extern Ike Naar <ike@iceland.freeshell.org> - 2017-03-25 19:50 +0000
Re: Can a variable be both static and extern supercat@casperkitty.com - 2017-03-25 13:20 -0700
Re: Can a variable be both static and extern jameskuyper@verizon.net - 2017-03-25 10:44 -0700
Re: Can a variable be both static and extern supercat@casperkitty.com - 2017-03-25 12:13 -0700
Page 1 of 2 [1] 2 Next page →
| From | acidlategamer@gmail.com |
|---|---|
| Date | 2017-03-24 04:23 -0700 |
| Subject | Can a variable be both static and extern |
| Message-ID | <6e7c0a5e-70aa-4163-b29a-3625ffc541d0@googlegroups.com> |
I was asked this in a interview
#include <stdio.h>
static int a;
extern int a;//
int main()
{
a = 10;
printf("%d\n", a);
return 0;
}
I said I will refrain from writing such things in a code, whatever the use case (because I really had no idea).
Later I told that it should be a compilation error as static makes a to live only while this file runs, extern makes it seem that a can live outside of this scope, that is contradictory. This program compiled.
1. Where I am wrong?
2. What would be your answer?
3. Is there any use case exists?
[toc] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-03-24 11:40 +0000 |
| Message-ID | <ob30dn$6b6$1@dont-email.me> |
| In reply to | #106887 |
On 24/03/17 11:23, acidlategamer@gmail.com wrote:
> I was asked this in a interview
>
> #include <stdio.h>
>
> static int a;
> extern int a;//
>
> int main()
> {
> a = 10;
> printf("%d\n", a);
> return 0;
> }
That isn't a question, unless the implied question is "what does this
code mean?" in which case the correct answer is "it means that whoever
wrote it needs to be transferred to Marketing".
The output of the code will be 10 and a newline character.
> I said I will refrain from writing such things in a code, whatever
> the use case (because I really had no idea).
You gave the right answer, but for the wrong reason. It's the right
answer because it's senseless to give 'a' file scope. It's also
senseless to call it 'a'.
> Later I told that it should be a compilation error as static makes a
> to live only while this file runs, extern makes it seem that a can live
> outside of this scope, that is contradictory. This program compiled.
I see no reason why it shouldn't compile.
> 1. Where I am wrong?
I don't think you /are/ wrong in this case.
> 2. What would be your answer?
Bring me the head of your project team leader!
> 3. Is there any use case exists?
No. It's stupid code. There certainly are cases where file scope
identifiers are better than the alternatives, but this isn't one of
those cases.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | acidlategamer@gmail.com |
|---|---|
| Date | 2017-03-24 04:54 -0700 |
| Message-ID | <9fd75dc8-e8c9-46cf-9d39-ce6c79c94e80@googlegroups.com> |
| In reply to | #106889 |
On Friday, March 24, 2017 at 5:10:30 PM UTC+5:30, Richard Heathfield wrote:
> On 24/03/17 11:23, acidlategamer@gmail.com wrote:
> > I was asked this in a interview
> >
> > #include <stdio.h>
> >
> > static int a;
> > extern int a;//
> >
> > int main()
> > {
> > a = 10;
> > printf("%d\n", a);
> > return 0;
> > }
>
> That isn't a question, unless the implied question is "what does this
> code mean?" in which case the correct answer is "it means that whoever
> wrote it needs to be transferred to Marketing".
>
> The output of the code will be 10 and a newline character.
>
> > I said I will refrain from writing such things in a code, whatever
> > the use case (because I really had no idea).
>
> You gave the right answer, but for the wrong reason. It's the right
> answer because it's senseless to give 'a' file scope. It's also
> senseless to call it 'a'.
>
> > Later I told that it should be a compilation error as static makes a
> > to live only while this file runs, extern makes it seem that a can live
> > outside of this scope, that is contradictory. This program compiled.
>
> I see no reason why it shouldn't compile.
>
> > 1. Where I am wrong?
>
> I don't think you /are/ wrong in this case.
>
> > 2. What would be your answer?
>
> Bring me the head of your project team leader!
>
> > 3. Is there any use case exists?
>
> No. It's stupid code. There certainly are cases where file scope
> identifiers are better than the alternatives, but this isn't one of
> those cases.
>
> --
> Richard Heathfield
> Email: rjh at cpax dot org dot uk
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line 4 vacant - apply within
The print statement and a = 10; is just written to avoid a warning.
The question was asked by a interviewer from a company named Aricent bangalore.
I checked more and something like this came up,
http://stackoverflow.com/questions/14403796/can-a-variable-be-declared-both-static-and-extern
I just don't understand why compiler writers leave spaces for such confusion.
extern makes linkage different than static, but the order of doing extern and static matter. How so?
static int a;
extern int a;
is legal and linkage is internal. Whereas
extern int a;
static int a;
is illegal and linkage conflict.
I just stumped over the fact that if in the first case compiler can act intelligent why not in the other case?
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-03-24 12:09 +0000 |
| Message-ID | <ob324j$c80$1@dont-email.me> |
| In reply to | #106892 |
On 24/03/17 11:54, acidlategamer@gmail.com wrote: <snip> > > The print statement and a = 10; is just written to avoid a warning. > The question was asked by a interviewer from a company named Aricent bangalore. > I checked more and something like this came up, > > http://stackoverflow.com/questions/14403796/can-a-variable-be-declared-both-static-and-extern > > I just don't understand why compiler writers leave spaces for such confusion. Well, if you stop people doing stupid things, you run the risk of stopping them doing clever things too. > extern makes linkage different than static, but the order of doing extern and static matter. How so? The page you cite (above) explains all that, I think. But the /real/ answer is: Patient: Doctor, it hurts when I do *this*. Doctor: Then don't do it. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-03-24 11:45 -0400 |
| Message-ID | <ob3ep7$ok8$1@dont-email.me> |
| In reply to | #106897 |
On 03/24/2017 08:09 AM, Richard Heathfield wrote: > On 24/03/17 11:54, acidlategamer@gmail.com wrote: > <snip> >> >> The print statement and a = 10; is just written to avoid a warning. >> The question was asked by a interviewer from a company named Aricent bangalore. >> I checked more and something like this came up, >> >> http://stackoverflow.com/questions/14403796/can-a-variable-be-declared-both-static-and-extern >> >> I just don't understand why compiler writers leave spaces for such confusion. > > Well, if you stop people doing stupid things, you run the risk of > stopping them doing clever things too. That would be a more persuasive argument if accompanied by at least one example of a clever thing allowed by this particular rule. >> extern makes linkage different than static, but the order of doing extern and static matter. How so? > > The page you cite (above) explains all that, I think. > > But the /real/ answer is: > > Patient: Doctor, it hurts when I do *this*. > Doctor: Then don't do it. The key question, and one I don't have an answer to, is why the standard goes out of it's way to make such code legal.
[toc] | [prev] | [next] | [standalone]
| From | raltbos@xs4all.nl (Richard Bos) |
|---|---|
| Date | 2017-03-25 22:27 +0000 |
| Message-ID | <58d6ea52.22587109@news.xs4all.nl> |
| In reply to | #106933 |
James Kuyper <jameskuyper@verizon.net> wrote:
> On 03/24/2017 08:09 AM, Richard Heathfield wrote:
> > On 24/03/17 11:54, acidlategamer@gmail.com wrote:
> >>
> >> http://stackoverflow.com/questions/14403796/can-a-variable-be-declared-both-static-and-extern
> >>
> >> I just don't understand why compiler writers leave spaces for such confusion.
They don't. It's the Standard which demands that this is legal, and what
it means, not the individual compilers.
> > Well, if you stop people doing stupid things, you run the risk of
> > stopping them doing clever things too.
>
> That would be a more persuasive argument if accompanied by at least one
> example of a clever thing allowed by this particular rule.
"counter.h":
extern unsigned long counter;
#define TICK() do {counter++;} while (0)
#define RESET() do (counter=0;} while (0)
#define PRINTCOUNTER() do {fprintf(LOGFILE, FORMAT, counter);} \
while (0)
Main file:
unsigned long counter=0;
#include "counter.h"
/* This file initialises the main counter. */
Normal use file:
#define FORMAT "Inventory count: %lu\n"
#include "counter.h"
/* All these files count using the main counter. */
Special use file, say "widgets.c":
/* Widgets are counted separately from other inventory. */
static unsigned long counter=0;
#define FORMAT ">>>Widgets: %lu\n"
#include "counter.h"
Another special file, "doodahs.c":
/* Doodahs are counted separately as well. */
/* Also, doodahs count starting from 2. */
static unsigned long counter=2;
#define FORMAT ">>>Doodahs (including default): %lu\n"
#include "counter.h"
I'll grant you, this is horrendous. But it _is_ moderately clever. I'll
also grant you that it is no more than moderately clever, but at least
it is a viable use case.
None of this is the real point, though, because that is...
> >> extern makes linkage different than static, but the order of doing extern and static matter. How so?
> >
> > The page you cite (above) explains all that, I think.
> >
> > But the /real/ answer is:
> >
> > Patient: Doctor, it hurts when I do *this*.
> > Doctor: Then don't do it.
>
> The key question, and one I don't have an answer to, is why the standard
> goes out of it's way to make such code legal.
...that it doesn't.
It goes out of its way to make the equivalent code with external linkage
objects legal. There's a very good reason for this: shared objects would
be impossible to declare type-safe if it didn't.
Once it did that, it would have to go out of its way _again_ to now make
it _il_legal for internal linkage objects. And that just isn't worth the
trouble. Once, yes, to make an essential feature possible. But not
twice, just to make a slightly confusing and potentially slightly useful
edge case impossible.
Richard
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-03-24 11:35 -0700 |
| Message-ID | <lnziga8qvg.fsf@kst-u.example.com> |
| In reply to | #106889 |
Richard Heathfield <rjh@cpax.org.uk> writes:
> On 24/03/17 11:23, acidlategamer@gmail.com wrote:
>> I was asked this in a interview
>>
>> #include <stdio.h>
>>
>> static int a;
>> extern int a;//
>>
>> int main()
>> {
>> a = 10;
>> printf("%d\n", a);
>> return 0;
>> }
>
> That isn't a question, unless the implied question is "what does this
> code mean?" in which case the correct answer is "it means that whoever
> wrote it needs to be transferred to Marketing".
>
> The output of the code will be 10 and a newline character.
>
>> I said I will refrain from writing such things in a code, whatever
>> the use case (because I really had no idea).
>
> You gave the right answer, but for the wrong reason. It's the right
> answer because it's senseless to give 'a' file scope. It's also
> senseless to call it 'a'.
>
>> Later I told that it should be a compilation error as static makes a
>> to live only while this file runs, extern makes it seem that a can live
>> outside of this scope, that is contradictory. This program compiled.
>
> I see no reason why it shouldn't compile.
>
>> 1. Where I am wrong?
>
> I don't think you /are/ wrong in this case.
>
>> 2. What would be your answer?
>
> Bring me the head of your project team leader!
>
>> 3. Is there any use case exists?
>
> No. It's stupid code. There certainly are cases where file scope
> identifiers are better than the alternatives, but this isn't one of
> those cases.
If code like this appeared in production, then yes, it would be
stupid. But the goal of this code isn't to print "10" and a newline;
that purpose would be served by `puts("10")`. The goal is to ask a
question about the interaction of "static" and "extern". Making the
code more elaborate so that the interaction actually makes sense
would just add clutter, and likely raise other irrelevant questions.
There is, in my opinion, nothing wrong with writing silly and useless
little sample programs whose purpose is to demonstrate a point
about the language. And it has serve that purpose here, by raising
questions about the reasoning behind a particular language rule.
--
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 | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-03-24 12:11 +0000 |
| Message-ID | <87poh6vpqv.fsf@bsb.me.uk> |
| In reply to | #106887 |
acidlategamer@gmail.com writes:
> I was asked this in a interview
>
> #include <stdio.h>
>
> static int a;
> extern int a;//
>
> int main()
> {
> a = 10;
> printf("%d\n", a);
> return 0;
> }
>
> I said I will refrain from writing such things in a code, whatever the
> use case (because I really had no idea).
That's a good answer. It's obviously confusing and not a good idea, but
I suppose the situation might arise as code gets changed without looking
ate the full picture.
> Later I told that it should be a compilation error
An "extern" declaration (note: not a definition) does not change the
linkage of a previously declared identifier with internal linkage so the
code if conforming and should compile.
I suppose there is some scope for misunderstanding here since "it should
be a compilation error" might mean that the interviewer knows that it is
not an error, but thinks it should be one.
> as static makes a to live only while this file runs, extern makes it
> seem that a can live outside of this scope, that is
> contradictory. This program compiled.
Yes, as it must with any conforming compiler.
> 1. Where I am wrong?
> 2. What would be your answer?
I'd say pretty much what you said, though I'd point out that is was
legal code and then I'd try to bite my tongue if told that that's wrong.
> 3. Is there any use case exists?
I'll pass on that one!
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | raltbos@xs4all.nl (Richard Bos) |
|---|---|
| Date | 2017-03-24 12:14 +0000 |
| Message-ID | <58d50784.12570828@news.xs4all.nl> |
| In reply to | #106887 |
acidlategamer@gmail.com wrote:
> I was asked this in a interview
>
> #include <stdio.h>
>
> static int a;
> extern int a;//
Let's get the obvious out of the way first. Yes, this is a stupid way to
write code. Don't write code like this.
However, it's legal, and it does what the interviewers thought it does.
That's not because it's a reasonable way to _write_ code, but because
code like this may end up being generated by reasonable #includes.
As for the legalities, this is what the Standard says. (I happen to be
using C99 at the moment, but AFAIAA this hasn't changed, although
paragraph numbers may have.)
6.2.2 #3: If the declaration of a file scope identifier for an object
or a function contains the storage class specifier static,
the identifier has internal linkage.
Your first a is a file scope identifier for an object, declared with
static. It therefore has internal linkage.
6.2.2 #4: For an identifier declared with the storage-class specifier
extern in a scope in which a prior declaration of that
identifier is visible, if the prior declaration specifies
internal or external linkage, the linkage of the identifier
at the later declaration is the same as the linkage
specified at the prior declaration. [...]
Your second a is declared with extern, in the file scope in which the
previous one is already visible; that previous declaration specified
internal linkage, and therefore, the second one does the same.
I'm not sure whether this counts as "hiding" or whether there legally is
only one a, but I do know this:
- your second declaration is the one that eventually gets used;
- because of "extern", it keeps the linkage of any previous declaration;
- because of "static", the previous declaration had internal linkage;
- therefore, a ends up being a file-scope identifier for an object with
internal linkage, and the rest of the code works just fine.
Now for why it is sane that things work this way, even if you shouldn't
explicitly write code this way.
Suppose you have a program consisting of several sources. One of these
sources declares an object (say "foo_counter"), and some of the other
sources need to modify that object when they create or destroy some
foos. Of course, you could go the whole Object Orientation route and add
functions to increase, decrease, and poll foo_counter; but suppose that
your program is currently quite simple (all it does is read input from
three sources and tally the total number of foos), so you don't want to
go that route.
What you do is have a header, say "foo.h", in which you declare
extern unsigned foo_counter;
which you then #include in every source which modifies or reads
foo_counter. (You'd already have that header, presumably, because you
also want some widely used functions for, say, nicely formatting the
foo_counter.)
Now you have a source file called "file_input.c" that starts
#include <stdio.h>
#include "foo.h"
int process_file(FILE *inputfile);
and a file called "serial_input.c" that does something similar, and so
forth, _and_ a file called "foo_common.c" that starts
#include <stdio.h>
unsigned foo_counter=1; // Foos count from 1;
#include "foo.h"
char *pretty_counter();
The result of _that_ #include "foo.h" will be almost the same as the two
declarations for a you have above, except that there is no "static".
In this example, it's not useful, in fact it would be wrong, to have the
"static". I could think of a case in which it would be useful, but it
would have to be a relatively complicated edge case. However, it would
be possible; and forbidding "static" on the identifiers which can be
"extern"ed would cause more problems than it would solve.
Richard
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-03-24 17:11 +0100 |
| Message-ID | <ob3gad$var$1@dont-email.me> |
| In reply to | #106899 |
On 24/03/17 13:14, Richard Bos wrote: <snip> > > In this example, it's not useful, in fact it would be wrong, to have the > "static". I could think of a case in which it would be useful, but it > would have to be a relatively complicated edge case. However, it would > be possible; and forbidding "static" on the identifiers which can be > "extern"ed would cause more problems than it would solve. > The example you gave here is just a standard global variable - defined (and initialised) in one file as "unsigned foo_counter = 1"; and declared as "extern unsigned foo_counter;" in a header file that is #included by all files that use it, including the file that defines it. While it is common to discourage the use of global (cross-module) variables like this, it is certainly standard practice in C and used heavily in some types of coding. The question is, are there any real uses of: static int foo; extern int foo; in the same translation unit (as different headers if you like) ? I can't think of any myself. I find it odd that this combination is allowed - I see no good uses for it, and it could easily occur as a mistake (especially for people who write "extern" declarations directly in the their C code, rather than just in headers). Of course, it could just be my lack of imagination here!
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2017-03-24 16:22 +0000 |
| Message-ID | <pJbBA.201100$XG2.105941@fx08.iad> |
| In reply to | #106935 |
David Brown <david.brown@hesbynett.no> writes: >On 24/03/17 13:14, Richard Bos wrote: > ><snip> > >> >> In this example, it's not useful, in fact it would be wrong, to have the >> "static". I could think of a case in which it would be useful, but it >> would have to be a relatively complicated edge case. However, it would >> be possible; and forbidding "static" on the identifiers which can be >> "extern"ed would cause more problems than it would solve. >> > >The example you gave here is just a standard global variable - defined >(and initialised) in one file as "unsigned foo_counter = 1"; and >declared as "extern unsigned foo_counter;" in a header file that is >#included by all files that use it, including the file that defines it. > >While it is common to discourage the use of global (cross-module) >variables like this, it is certainly standard practice in C and used >heavily in some types of coding. > > >The question is, are there any real uses of: > >static int foo; >extern int foo; > >in the same translation unit (as different headers if you like) ? > >I can't think of any myself. I find it odd that this combination is >allowed - I see no good uses for it, and it could easily occur as a >mistake (especially for people who write "extern" declarations directly >in the their C code, rather than just in headers). > >Of course, it could just be my lack of imagination here! > While uncommon, one need not organize all #include preprocessor directives before file-scope declarations in a given translation unit.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-03-24 17:38 +0100 |
| Message-ID | <ob3ht8$5fo$1@dont-email.me> |
| In reply to | #106937 |
On 24/03/17 17:22, Scott Lurndal wrote: > David Brown <david.brown@hesbynett.no> writes: >> On 24/03/17 13:14, Richard Bos wrote: >> >> <snip> >> >>> >>> In this example, it's not useful, in fact it would be wrong, to have the >>> "static". I could think of a case in which it would be useful, but it >>> would have to be a relatively complicated edge case. However, it would >>> be possible; and forbidding "static" on the identifiers which can be >>> "extern"ed would cause more problems than it would solve. >>> >> >> The example you gave here is just a standard global variable - defined >> (and initialised) in one file as "unsigned foo_counter = 1"; and >> declared as "extern unsigned foo_counter;" in a header file that is >> #included by all files that use it, including the file that defines it. >> >> While it is common to discourage the use of global (cross-module) >> variables like this, it is certainly standard practice in C and used >> heavily in some types of coding. >> >> >> The question is, are there any real uses of: >> >> static int foo; >> extern int foo; >> >> in the same translation unit (as different headers if you like) ? >> >> I can't think of any myself. I find it odd that this combination is >> allowed - I see no good uses for it, and it could easily occur as a >> mistake (especially for people who write "extern" declarations directly >> in the their C code, rather than just in headers). >> >> Of course, it could just be my lack of imagination here! >> > > While uncommon, one need not organize all #include preprocessor > directives before file-scope declarations in a given translation > unit. > That's true. (And there are sometimes good reasons for having #include's in odd places.) But to get the "static int foo; extern int foo;" pair you would have to be writing: // in "file.c" // Here is a file-local variable foo: static int foo; #include "header.h" // in "header.h" // Here is a declaration of a program-global variable foo: extern int foo; And that second declaration is then wrong - you are /not/ declaring a program-global variable. You are re-declaring an existing file-local variable. So if you use "foo" later on, you are likely to be using the /wrong/ foo. It would be a fine example of why this ought to have been an error.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-03-24 12:23 -0400 |
| Message-ID | <ob3gvq$1mg$1@dont-email.me> |
| In reply to | #106935 |
On 03/24/2017 12:11 PM, David Brown wrote: ... > The question is, are there any real uses of: > > static int foo; > extern int foo; > > in the same translation unit (as different headers if you like) ? > > I can't think of any myself. I find it odd that this combination is > allowed - I see no good uses for it, and it could easily occur as a > mistake (especially for people who write "extern" declarations directly > in the their C code, rather than just in headers). > > Of course, it could just be my lack of imagination here! It probably is - and I say that while having the same lack of imagination. The relevant clause in the standard serves no other purpose than to define the meaning of this combination of declarations, so it's presence must have been intentional - the committee must have had a reason for approving that wording. I have no idea what that reason was.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-03-24 17:41 +0100 |
| Message-ID | <ob3i26$5fo$2@dont-email.me> |
| In reply to | #106938 |
On 24/03/17 17:23, James Kuyper wrote: > On 03/24/2017 12:11 PM, David Brown wrote: > ... >> The question is, are there any real uses of: >> >> static int foo; >> extern int foo; >> >> in the same translation unit (as different headers if you like) ? >> >> I can't think of any myself. I find it odd that this combination is >> allowed - I see no good uses for it, and it could easily occur as a >> mistake (especially for people who write "extern" declarations directly >> in the their C code, rather than just in headers). >> >> Of course, it could just be my lack of imagination here! > > It probably is - and I say that while having the same lack of > imagination. The relevant clause in the standard serves no other purpose > than to define the meaning of this combination of declarations, so it's > presence must have been intentional - the committee must have had a > reason for approving that wording. I have no idea what that reason was. > Careful - Richard will bite you for arguing by appealing to authority! There is probably some important historical code that has this combination which had been allowed by an existing compiler, and the standards committee did not want to break the old code. Compatibility with existing code is the reason behind a lot of strange things in the standards.
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2017-03-24 09:57 -0700 |
| Message-ID | <33c00425-2c2c-4586-b355-868caf6eb85c@googlegroups.com> |
| In reply to | #106943 |
On Friday, March 24, 2017 at 12:41:36 PM UTC-4, David Brown wrote: > On 24/03/17 17:23, James Kuyper wrote: > > On 03/24/2017 12:11 PM, David Brown wrote: > > ... > >> The question is, are there any real uses of: > >> > >> static int foo; > >> extern int foo; > >> > >> in the same translation unit (as different headers if you like) ? > >> > >> I can't think of any myself. I find it odd that this combination is > >> allowed - I see no good uses for it, and it could easily occur as a > >> mistake (especially for people who write "extern" declarations directly > >> in the their C code, rather than just in headers). > >> > >> Of course, it could just be my lack of imagination here! > > > > It probably is - and I say that while having the same lack of > > imagination. The relevant clause in the standard serves no other purpose > > than to define the meaning of this combination of declarations, so it's > > presence must have been intentional - the committee must have had a > > reason for approving that wording. I have no idea what that reason was. > > > > Careful - Richard will bite you for arguing by appealing to authority! I didn't say that the committee must have had sufficient reason to justify this decision, or even that they had a good but inadequate reason. They could have had a very bad reason. However, it's not something they could have written by accident - so they must have had some reason.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-03-24 10:38 -0700 |
| Message-ID | <4efa0d86-f953-4200-ad92-7d3154416541@googlegroups.com> |
| In reply to | #106943 |
On Friday, March 24, 2017 at 11:41:36 AM UTC-5, David Brown wrote:
> There is probably some important historical code that has this
> combination which had been allowed by an existing compiler, and the
> standards committee did not want to break the old code. Compatibility
> with existing code is the reason behind a lot of strange things in the
> standards.
If a header file contains an inline function which uses an extern variable,
should that preclude the use of that name for static variables in code that
includes it? It would hardly seem implausible that such code might exist,
since people don't generally expect to need to worry about name collisions
between static variables and globals that are used in other areas of the
code.
In a related note, is there anything in the Standard that would suggest that
the existence of the following in one compilation unit should prevent
execution of a program that is otherwise strictly conforming?
void test1(void)
{
extern struct {int x;} *foo;
}
void test2(void)
{
extern struct {int x;} *foo;
}
The types of the two declarations aren't compatible with each other, but
if another compilation unit were to contain:
struct {int x;} *foo;
that definition should be compatible with both of the above declarations
since the structure definitions in separate compilation units are compatible
if neither has a tag and they contain the same members in the same order.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-03-24 18:24 +0000 |
| Message-ID | <ob3o2p$rak$1@dont-email.me> |
| In reply to | #106943 |
On 24/03/17 16:41, David Brown wrote: > On 24/03/17 17:23, James Kuyper wrote: >> On 03/24/2017 12:11 PM, David Brown wrote: >> ... >>> The question is, are there any real uses of: >>> >>> static int foo; >>> extern int foo; >>> >>> in the same translation unit (as different headers if you like) ? >>> >>> I can't think of any myself. I find it odd that this combination is >>> allowed - I see no good uses for it, and it could easily occur as a >>> mistake (especially for people who write "extern" declarations directly >>> in the their C code, rather than just in headers). >>> >>> Of course, it could just be my lack of imagination here! >> >> It probably is - and I say that while having the same lack of >> imagination. The relevant clause in the standard serves no other purpose >> than to define the meaning of this combination of declarations, so it's >> presence must have been intentional - the committee must have had a >> reason for approving that wording. I have no idea what that reason was. >> > > Careful - Richard will bite you for arguing by appealing to authority! Ha, and perhaps ha as well. Nevertheless, appeals to the Standard are appeals to /appropriate/ authority. Appeals to any other authority, no matter how prestigious, are fallacious. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-03-25 10:47 -0400 |
| Message-ID | <b0a05f7d-ba76-3ffd-7b45-0f53b9fd766b@verizon.net> |
| In reply to | #106971 |
On 03/24/2017 02:24 PM, Richard Heathfield wrote: > On 24/03/17 16:41, David Brown wrote: ... >> Careful - Richard will bite you for arguing by appealing to authority! > > Ha, and perhaps ha as well. > > Nevertheless, appeals to the Standard are appeals to /appropriate/ > authority. Appeals to any other authority, no matter how prestigious, > are fallacious. I think there's a key distinction to be made, and "appropriate" isn't quite the right one. When the question is "What does Authority X say about statement q?", then there is absolutely no evidence more relevant than the actual words that came from X. Other evidence can be relevant: evidence that the words were incorrectly recorded, or even faked, evidence indicating that X was lying (as a document, rather than a person, the C standard can't lie; but the C committee could), evidence about X's cultural background which might change the meaning conveyed by X's words, etc., but the actual words of X are always the primary source. And that is why the Standard itself is the single most relevant source of information about what the Standard says, with the C committee being the place to go if there's any ambiguity about the meaning of those words. However, if the question is "Is statement q true?", arguments citing X's belief that q is true are, at best, useful supporting arguments, no matter how appropriate X is as an authority. If X believes that q is true, X must know of some argument that X considers valid, with that conclusion. That argument is a far more relevant than the simple fact that X believes q to be true. That's because, no matter how good X's credentials are, X might be mistaken, or even lying. If X gives you an explanation, you can examine it to judge whether it's a valid one. If X refuses to explain, you have just cause to suspect that X doesn't have a good explanation (there can be legitimate reasons for not explaining, such as "National Security issues" - but the problem is that an authority who doesn't have a good explanation is likely to claim that he actually has one of those legitimate reasons for not providing one, which tends to weaken even the legitimate reasons). Many people claim to know of at least one Authority guaranteed to never lie and never be mistaken, but I've never seen a valid argument justifying their belief in the existence of that guarantee (and for many such Authorities, I've never even seen a valid argument for believing in the existence of that Authority, with or without guaranteed honesty and infallability).
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-03-25 16:48 +0000 |
| Message-ID | <ob66rd$phv$1@dont-email.me> |
| In reply to | #107042 |
On 25/03/17 14:47, James R. Kuyper wrote: > On 03/24/2017 02:24 PM, Richard Heathfield wrote: >> On 24/03/17 16:41, David Brown wrote: > ... >>> Careful - Richard will bite you for arguing by appealing to authority! >> >> Ha, and perhaps ha as well. >> >> Nevertheless, appeals to the Standard are appeals to /appropriate/ >> authority. Appeals to any other authority, no matter how prestigious, >> are fallacious. > > I think there's a key distinction to be made, and "appropriate" isn't > quite the right one. > > When the question is "What does Authority X say about statement q?", > then there is absolutely no evidence more relevant than the actual words > that came from X. Other evidence can be relevant: evidence that the > words were incorrectly recorded, or even faked, evidence indicating that > X was lying (as a document, rather than a person, the C standard can't > lie; but the C committee could), evidence about X's cultural background > which might change the meaning conveyed by X's words, etc., but the > actual words of X are always the primary source. And that is why the > Standard itself is the single most relevant source of information about > what the Standard says, with the C committee being the place to go if > there's any ambiguity about the meaning of those words. Right so far... > However, if the question is "Is statement q true?", arguments citing X's > belief that q is true are, at best, useful supporting arguments, no > matter how appropriate X is as an authority. With Pontius Pilate, I find myself asking "What is truth?" C may be considered to be a formal system, and ISO/IEC 9899 constitutes the definition of that system. Any question about C is therefore an enquiry about the consequences of applying "the rules" (i.e. ISO/IEC 9899) to a particular language construct. And so the *only* relevant authority is ISO/IEC 9899, because any other authority cannot help but take second place to the language definition itself. The only way in which the Standard can be superseded on a question /about C/ is when a particular version of that Standard is invoked, in which case it trumps later Standards /for that question/, but without specific mention of a version (C90, C99, C11, etc), we have to assume that the latest ISO release is the /definitive/ answer to all questions about the language. > If X believes that q is > true, X must know of some argument that X considers valid, with that > conclusion. That argument is a far more relevant than the simple fact > that X believes q to be true. Not when X is ISO/IEC 9899. It is sufficient for X to /state/ that q is true, and it is then, by definition, true. > That's because, no matter how good X's > credentials are, X might be mistaken, or even lying. Oddly, this turns out not to matter. If q is a question about C and X is ISO/IEC 9899, then X's mistaken understanding of q is nevertheless correct... and even X's lies about q are, by definition, true! :-) > Many people claim to know of at least one Authority guaranteed to never > lie and never be mistaken, but I've never seen a valid argument > justifying their belief in the existence of that guarantee (and for many > such Authorities, I've never even seen a valid argument for believing in > the existence of that Authority, with or without guaranteed honesty and > infallability). ISO/IEC 9899 is such an Authority. Even where it lies, it tells the truth, and even where it is mistaken, it is correct until the application of a DR, whereupon it effortlessly changes its mind and is /still/ correct. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-03-25 10:31 -0700 |
| Message-ID | <lna8898dq3.fsf@kst-u.example.com> |
| In reply to | #107045 |
Richard Heathfield <rjh@cpax.org.uk> writes:
[...]
> ISO/IEC 9899 is such an Authority. Even where it lies, it tells the
> truth, and even where it is mistaken, it is correct until the
> application of a DR, whereupon it effortlessly changes its mind and is
> /still/ correct.
And what if the Authority contradicts itself?
For example, the term "expression" is defined both by the grammar:
expression:
assignment-expression
expression , assignment-expression
(with a bunch of rules recursively defining "assignment-expression"
et al) and by the definition in 6.5p1:
An *expression* is a sequence of operators and operands that
specifies computation of a value, or that designates an object
or a function, or that generates side effects, or that performs
a combination thereof.
The grammar clearly indicates that 42 is an expression. The English
definition indicates that it is not (it contains no operators and
therefore no operands). (And no, you can't reasonably invent a null
operator that has 42 as its operand; the normative definition of
"operator" in 6.4.6 doesn't permit that.)
The intent is clear enough (42 is an expression and the definition
in 6.5p1 is flawed), but we can't determine that without applying
common sense rules from outside the standard.
--
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]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web