By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,369 Members | 1,682 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,369 IT Pros & Developers. It's quick & easy.

Trying to declare identifier locally and hide a file scope identifier

P: n/a
The code below isn't compiling for me (error message: conflicting types
for 'total' - pointing to the extern declaration).

Why wouldn't this work, since the types are different, the extern
declaration obviously refers to the 'long total' in total.c? Is my
compiler wrong?

total.c
-------
long total = 30;
main.c
-------

#include <stdio.h>
#include <stdlib.h>

static int total = 20;

int main(void)
{
long temp;
extern long total;

/* rest of main */

temp = total;

printf("%d\n", temp);

system("PAUSE");
return 0;
}

Nov 14 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Kobu wrote:
The code below isn't compiling for me (error message: conflicting types for 'total' - pointing to the extern declaration).

Why wouldn't this work, since the types are different, the extern
declaration obviously refers to the 'long total' in total.c? Is my
compiler wrong?

total.c
-------
long total = 30;
main.c
-------

#include <stdio.h>
#include <stdlib.h>

static int total = 20;

int main(void)
{
long temp;
extern long total;

/* rest of main */

temp = total;

printf("%d\n", temp);

system("PAUSE");
return 0;
}

I tried the program with main.c changed to the following, and it still
didn't work (same error message):
main.c - 2nd version
------

#include <stdio.h>
#include <stdlib.h>

static int total = 20;

int main(void)
{
int total;
{
long temp;
extern long total;

temp = total;
printf("%d\n", temp);
}
return 0;
}
Shouldn't the 'int total' in main force the 'extern long total' to have
external linkage?

Nov 14 '05 #2

P: n/a
Kobu wrote:
The code below isn't compiling for me (error message: conflicting types
for 'total' - pointing to the extern declaration).
You have an identifier with internal linkage at file scope, and then you
"import" another identifier of the same name, which has external linkage
and therefore cannot refer to the same object. As a result, the names
collide.
Why wouldn't this work, since the types are different
Since when does that matter? This is also not allowed:
int a;
double a;
There is no overloading in C.
total.c
-------
long total = 30;
main.c
-------

#include <stdio.h>
#include <stdlib.h>

static int total = 20;


What I'm not completely sure about: Is it legal up to this point? Can you
define an identifier with external linkage in one source file and one of
the same name with internal linkage in another file, as long as you do not
declare the former there also? My Linux system links it without a warning,
but I'm not sure if it's being overly generous.
Christian
Nov 14 '05 #3

P: n/a
On Thu, 24 Feb 2005 10:08:21 +0100, Christian Kandeler
<ch****************@hob.de_invalid> wrote:
total.c
-------
long total = 30;
main.c
-------

#include <stdio.h>
#include <stdlib.h>

static int total = 20;


What I'm not completely sure about: Is it legal up to this point? Can you
define an identifier with external linkage in one source file and one of
the same name with internal linkage in another file, as long as you do not
declare the former there also? My Linux system links it without a warning,
but I'm not sure if it's being overly generous.


Certainly it's legal, that's the point of having internal linkage, it's
known only to that module. If I had to try to predict every identifier
that some module somewhere in a large system might have defined as an
external name it would be totally unworkable.

(Of course, if C imported the "namespace" concept from C++ it would make
writing libraries much simpler. But don't hold your breath for that...)

Chris C
Nov 14 '05 #4

P: n/a
On Wed, 23 Feb 2005 21:43:34 -0800, Kobu wrote:
Kobu wrote:
The code below isn't compiling for me (error message: conflicting types
for 'total' - pointing to the extern declaration).

Why wouldn't this work, since the types are different, the extern
declaration obviously refers to the 'long total' in total.c? Is my
compiler wrong?
Your compiler is correct.
total.c
-------
long total = 30;
main.c
-------

#include <stdio.h>
#include <stdlib.h>

static int total = 20;

int main(void)
{
long temp;
extern long total;

/* rest of main */

temp = total;

printf("%d\n", temp);

system("PAUSE");
return 0;
}


The standard says in 6.2.2.p4:

"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. If no prior declaration is visible,
or if the prior declaration specifies no linkage, then the identifier has
external linkage."

So both declarations of total in main.c have internal linkage, which means
that 'extern long total' is linked to 'static int total = 20' in main.c
and not 'long total = 20' in total.c. However the types are incompatible
for that linking.
I tried the program with main.c changed to the following, and it still
didn't work (same error message):
main.c - 2nd version
------

#include <stdio.h>
#include <stdlib.h>

static int total = 20;

int main(void)
{
int total;
{
long temp;
extern long total;

temp = total;
printf("%d\n", temp);
}
return 0;
}
}
}
Shouldn't the 'int total' in main force the 'extern long total' to have
external linkage?


Yes it should because 'int total' is now the prior declaration that is
visible at 'extern long total', and it has no linkage. However the
standard also says in 6.2.2p7:

"If, within a translation unit, the same identifier appears with both internal and external
linkage, the behavior is undefined."

This situation occurs in your new code. However if I understand you
correctly your compiler produces a misleading diagnostic.

Lawrence
Nov 14 '05 #5

P: n/a
Lawrence Kirby wrote:
On Wed, 23 Feb 2005 21:43:34 -0800, Kobu wrote:
Kobu wrote:
The code below isn't compiling for me (error message: conflicting types
for 'total' - pointing to the extern declaration).

Why wouldn't this work, since the types are different, the extern
declaration obviously refers to the 'long total' in total.c? Is my
compiler wrong?
Your compiler is correct.


[snipped my incorrect code example]
}
Shouldn't the 'int total' in main force the 'extern long total' to have external linkage?


Yes it should because 'int total' is now the prior declaration that

is visible at 'extern long total', and it has no linkage. However the
standard also says in 6.2.2p7:

"If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined."

This situation occurs in your new code. However if I understand you
correctly your compiler produces a misleading diagnostic.

Lawrence

I have a question about internal linkage. I want to define a
file-scope variable with internal linkage (ex: static int i; at top of
translation unit) and then I want this to be shadowed by a different
'i' within a large function. Then inside a nested block in the
function, I want to refer to the file-scope 'i'.

Something like this:

static int i; /* file-scope, internal linkage */

void foo()
{
int i; /* block scope, no linkage */

/* some code here */
{
extern int i; /* block, internal linkage */

/* some code here */
}

/* some code here */
}

/* rest of translation unit */

Your post claims that this is how the C Standard treats deeply nested
'extern' declarations, but my compiler is complaining. Your post:
http://groups-beta.google.com/group/...a14942f7fabe80
My compiler is complaining about internal and external declarations of
same identifier (which tells me the deeply nested 'i' is defaulting to
external linkage, instead of "grabbing" the linkage from the previous
file scope declaration of 'i', like your old post explain -- which is
always what I thought happened).

The standard mentions this "grabbing affect," much like your post did,
but it's defaulting to external. Can someone clear this up (possibly
test this on their compiler, or point out my mistake).

Nov 14 '05 #6

P: n/a
Kobu wrote:

I have a question about internal linkage. I want to define a
file-scope variable with internal linkage (ex: static int i; at top of translation unit) and then I want this to be shadowed by a different
'i' within a large function. Then inside a nested block in the
function, I want to refer to the file-scope 'i'.

Something like this:

static int i; /* file-scope, internal linkage */

void foo()
{
int i; /* block scope, no linkage */

/* some code here */
{
extern int i; /* block, internal linkage */

/* some code here */
}

/* some code here */
}

/* rest of translation unit */

Your post claims that this is how the C Standard treats deeply nested
'extern' declarations, but my compiler is complaining. Your post:
http://groups-beta.google.com/group/...a14942f7fabe80

My compiler is complaining about internal and external declarations of same identifier (which tells me the deeply nested 'i' is defaulting to external linkage, instead of "grabbing" the linkage from the previous
file scope declaration of 'i', like your old post explain -- which is
always what I thought happened).

The standard mentions this "grabbing affect," much like your post did, but it's defaulting to external. Can someone clear this up (possibly
test this on their compiler, or point out my mistake).


Your compiler is right and Lawrence's explanation was
a little off in his old post. extern will, as you say,
"grab" the linkage of any visible declaration that
doesn't have no lnkage. The static int i at file scope
is not visible at the point where you declare the nested
extern int i, so the only declaration for i it sees at
that point is the no linkage declaration just inside the
opening brace for void food(). This causes it to default
to external linkage, which creates a conflict with the
internal linkage of the file scope i. Your compiler is
right.

Nov 14 '05 #7

P: n/a

E. Robert Tisdale wrote:
Kobu wrote:

I have a question about internal linkage. I want to define a
file-scope variable with internal linkage (ex: static int i; at
top

Snipped a lot of stuff unrelated to my request below.
This causes it to default
to external linkage, which creates a conflict with the
internal linkage of the file scope i. Your compiler is
right.


I prefer getting an answer from a non-troll.

Nov 14 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.