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


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

Can a variable be both static and extern

Started byacidlategamer@gmail.com
First post2017-03-24 04:23 -0700
Last post2017-03-25 12:13 -0700
Articles 20 on this page of 26 — 12 participants

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


Contents

  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 →


#106887 — Can a variable be both static and extern

Fromacidlategamer@gmail.com
Date2017-03-24 04:23 -0700
SubjectCan 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]


#106889

FromRichard Heathfield <rjh@cpax.org.uk>
Date2017-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]


#106892

Fromacidlategamer@gmail.com
Date2017-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]


#106897

FromRichard Heathfield <rjh@cpax.org.uk>
Date2017-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]


#106933

FromJames Kuyper <jameskuyper@verizon.net>
Date2017-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]


#107081

Fromraltbos@xs4all.nl (Richard Bos)
Date2017-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]


#106977

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#106898

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#106899

Fromraltbos@xs4all.nl (Richard Bos)
Date2017-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]


#106935

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#106937

Fromscott@slp53.sl.home (Scott Lurndal)
Date2017-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]


#106942

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#106938

FromJames Kuyper <jameskuyper@verizon.net>
Date2017-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]


#106943

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#106951

Fromjameskuyper@verizon.net
Date2017-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]


#106958

Fromsupercat@casperkitty.com
Date2017-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]


#106971

FromRichard Heathfield <rjh@cpax.org.uk>
Date2017-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]


#107042

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-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]


#107045

FromRichard Heathfield <rjh@cpax.org.uk>
Date2017-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]


#107047

FromKeith Thompson <kst-u@mib.org>
Date2017-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