redeclaration of 'p' with no linkage

R

Ravi

#include <stdio.h>
int main(void)
{
int i, j, *p;
i = 25;
j = 100;
int *p = &i;
}

When I compiled the above code with gcc I goth the message :
"redeclaration of 'p' with no linkage" .
What does this mean. Can You please explain?
 
P

pete

Ravi said:
#include <stdio.h>
int main(void)
{
int i, j, *p;
i = 25;
j = 100;
int *p = &i;
}

When I compiled the above code with gcc I goth the message :
"redeclaration of 'p' with no linkage" .
What does this mean.

It means that p has no linkage and that you declared p twice.
Can You please explain?

It's easier just to fix the code:

#include <stdio.h>

int main(void)
{
int i, j, *p;

i = 25;
j = 100;
p = &i;
}
 
C

CBFalconer

Ravi said:
#include <stdio.h>
int main(void) {
int i, j, *p;
i = 25;
j = 100;
int *p = &i;
}

When I compiled the above code with gcc I goth the message :
"redeclaration of 'p' with no linkage" .
What does this mean. Can You please explain?

You already declared it in the first line.
 
M

Mark McIntyre

#include <stdio.h>
int main(void)
{
int i, j, *p;

here you declared p as a pointr to an int.
i = 25;
j = 100;
int *p = &i;

here, you tried to declare it again.

Both declarations don't specify the linkage - that is, they don't say
that the object is extern (external linkage) or static (internal
linkage) .

Such objects have 'no linkage' and you can't have two of them in the
same scope. See 6.2.2 of the Standard.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
K

Kenneth Brody

Mark said:
here you declared p as a pointr to an int.

here, you tried to declare it again.

Both declarations don't specify the linkage - that is, they don't say
that the object is extern (external linkage) or static (internal
linkage) .

Such objects have 'no linkage' and you can't have two of them in the
same scope. See 6.2.2 of the Standard.

Does that mean that this should be valid?

void foo(void)
{
static int *p;
int i;
extern int *p = &i;
}

My compiler doesn't allow it. (Ditto with other combinations of
static/extern/none.) They all give "'p' : redefinition".

(Not that I would ever knowingly use such a construct.)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Kenneth said:
Does that mean that this should be valid?

void foo(void)
{
static int *p;
int i;
extern int *p = &i;
}

My compiler doesn't allow it. (Ditto with other combinations of
static/extern/none.) They all give "'p' : redefinition".

In this case, static does not imply internal linkage. A block-scope object
defined with the keyword 'static' has no linkage. A file-scope object
defined with the keyword 'static' has internal linkage.

Additionally, objects with static storage duration must have constant
initialisers, which &i is not, and block-scope declarations of objects with
linkage may not even have any initialiser at all.

But your compiler should not object to

void foo(void)
{
extern int *p;
extern int *p;
}

nor to

static int *p;
void foo(void)
{
extern int *p;
extern int *p;
}
 
M

Mark McIntyre

Does that mean that this should be valid?

void foo(void)
{
static int *p;
int i;
extern int *p = &i;
}

My compiler doesn't allow it.

Interesting - I think that this ought to be allowed by 6.2.2p4,
though I'm happy to be corrected. Is this a C89 vs C99 thing?

"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."
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
P

pete

Mark said:
Interesting - I think that this ought to be allowed by 6.2.2p4,
though I'm happy to be corrected. Is this a C89 vs C99 thing?

"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."

I can't see it in C89.

6.1.2.2 Linkages of identifiers
An identifier declared in different scopes or in the same scope
more than once can be made
to refer to the same object or function by a process called linkage.
There are three kinds of linkage: external, internal, and none.
In the set of translation units and libraries that constitutes an
entire program, each instance of a particular identifier with
external linkage denotes the same object or function. Within one
translation unit, each instance of an identifier with internal
linkage denotes the same object or
function. Identifiers with no linkage denote unique entities.
If the declaration of a file scope identifier for an object
or a function contains the storageclass
specifier static, the identifier has internal linkage.
13
If the declaration of an identifier for an object or a function
contains the storage-class specifier extern, the identifier has
the same linkage as any visible declaration of the identifier
with file scope. If there is no visible declaration with file
scope, the identifier has external linkage.
If the declaration of an identifier for a function has no
storage-class specifier, its linkage is determined exactly
as if it were declared with the storage-class specifier extern.
If the declaration of an identifier for an object has file scope
and no storage-class specifier, its linkage is external.
The following identifiers have no linkage:
an identifier declared to be anything other than an object
or a function:
an identifier declared to be a function parameter;
a block scope identifier for an object declared without
the storage-class specifier extern.
If, within a translation unit, the same identifier appears
with both internal and external linkage, the behavior is undefined.
 
P

Peter 'Shaggy' Haywood

Groovy hepcat Mark McIntyre was jivin' in comp.lang.c on Tue, 21 Aug
2007 9:16 am. It's a cool scene! Dig it.
Interesting - I think that this ought to be allowed by 6.2.2p4,
though I'm happy to be corrected. Is this a C89 vs C99 thing?

"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."

Identifiers declared within a block and without the extern keyword
have no linkage.

-----------------------------------------------------------------------
6.2.2 Linkages of identifiers
....
2 ... Each declaration of an identifier with no linkage denotes a unique
entity.
....
6 The following identifiers have no linkage: ... a block scope
identifier for an object declared without the storage-class specifier
extern.
-----------------------------------------------------------------------

Therefore, the above extern declaration of p denotes a separate object
with external linkage, clashing with the previous static declaration.
Also, since it has block scope, the extern declaration is not allowed
to have an initialiser; so that's another problem.

-----------------------------------------------------------------------
6.7.8 Initialization
....
Constraints
....
5 If the declaration of an identifier has block scope, and the
identifier has external or internal linkage, the declaration shall have
no initializer for the identifier.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,052
Latest member
LucyCarper

Latest Threads

Top