473,779 Members | 2,038 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Doubts about Linkage Rules

source: http://rm-f.net/~orange/devel/specif...t.html#3.1.2.2

there are two passages in this paragraph i can't fully understand:

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

in particular: "the identifier has the same linkage as /any/ /visible/
declaration of the identifier with file scope"

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

i can't imagine an example of an identifier having both internal and
external linkage...
Apr 17 '06 #1
13 2096
fctk wrote:
source: http://rm-f.net/~orange/devel/specif...t.html#3.1.2.2

there are two passages in this paragraph i can't fully understand:

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

in particular: "the identifier has the same linkage as /any/ /visible/
declaration of the identifier with file scope"
It means that the following is a legal declaration of foo with file
linkage scope:

static int foo;
extern int foo;

and this a legal declaration of bar with external linkage scope:

int bar;
extern int bar;

The rationale document for C89 explains how this requirement allows the
implementation of a one-pass compiler that generates intermediate
assembly code.

Note that C99 clarifies the *visible* part of the specification as
follows (6.2.2):

"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."
2) "If, within a translation unit, the same identifier appears with both
internal and external linkage, the behavior is undefined."

i can't imagine an example of an identifier having both internal and
external linkage...


This is not allowed:

static int bar;
int bar;

--
Diomidis Spinellis
Code Quality: The Open Source Perspective (Addison-Wesley 2006)
http://www.spinellis.gr/codequality
Apr 17 '06 #2
fctk <-> wrote:

there are two passages in this paragraph i can't fully understand: [...] in particular: "the identifier has the same linkage as /any/ /visible/
declaration of the identifier with file scope"
Visibility of identifiers is discussed in 6.2.1p2. Consider:

extern int i;
static int i;

The second declaration is not yet visible at the first declaration, so
the first declaration declares i to have external linkage.
i can't imagine an example of an identifier having both internal and
external linkage...


See above. :-)

If the declarations were reversed, all would be well since the "static"
declaration would be visible at the "extern" declaration and thus the
"extern" declaration would declare "i" with internal linkage, too.

-Larry Jones

How am I supposed to learn surgery if I can't dissect anything? -- Calvin
Apr 17 '06 #3
Diomidis Spinellis ha scritto:
fctk wrote:
2) "If, within a translation unit, the same identifier appears with
both internal and external linkage, the behavior is undefined."

i can't imagine an example of an identifier having both internal and
external linkage...

This is not allowed:

static int bar;
int bar;


i can't understand why there is a problem with:

static int bar;
int bar;

let me expand the previous example to something as:

static int bar; /* first declaration of `bar' */

void f1(void) {
bar;
}

int bar; /* second declaration of `bar' */

void f2(void) {
bar;
}

first of all let's highlight the scopes of the two declarations of
`bar'; i will put an /* 1 */ in front of all lines that belongs to the
scope of the first declaration, and an /* 2 */ in front of all lines
that belong to the scope of the second declaration:

static int bar; /* first declaration of `bar' */
/* 1 */
/* 1 */ void f1(void) {
/* 1 */ bar;
/* 1 */ }
/* 1 */
int bar; /* second declaration of `bar' */
/* 2 */
/* 2 */ void f2(void) {
/* 2 */ bar;
/* 2 */ }

both declarations of `bar' have file-scope, becouse they are put outside
of any block and outside of any list of parameter declarations in a
function definition.

please note that, as far as i know, given a certain identifier `foo',
the scope of a declaration of `foo' and the scope of another declaration
of `foo' *can't* overlap. overlapping is possible only for the scopes of
*different* identifiers declarations.

the relevant rules here for the linkage are:

1) If the declaration of an identifier for an object or a function has
file scope and contains the storage-class specifier static, the
identifier has internal linkage.

2) If the declaration of an identifier for an object has file scope and
no storage-class specifier, its linkage is external.

so for rule 1) all instances of identifier `bar' within the scope of the
first declaration of `bar' have internal-linkage, while for rule 2) all
instances of identifier `bar' within the scope of the second declaration
of `bar' have external-linkage:

static int bar; /* first declaration of `bar' */
/* 1 */
/* 1 */ void f1(void) {
/* 1 */ bar; /* this instance has internal-linkage */
/* 1 */ }
/* 1 */
int bar; /* second declaration of `bar' */
/* 2 */
/* 2 */ void f2(void) {
/* 2 */ bar; /* this instance has external-linkage */
/* 2 */ }

so as far as i know there is no instance of some identifier with *both*
internal-linkage and external-linkage.

of course my reasoning is wrong in some points, but i can't understand
where.

sorry for the long message.
Apr 18 '06 #4

fctk wrote:
Diomidis Spinellis ha scritto:
fctk wrote:
2) "If, within a translation unit, the same identifier appears with
both internal and external linkage, the behavior is undefined."

i can't imagine an example of an identifier having both internal and
external linkage...

This is not allowed:

static int bar;
int bar;


i can't understand why there is a problem with:


<snip>
first of all let's highlight the scopes of the two declarations of
`bar'; i will put an /* 1 */ in front of all lines that belongs to the
scope of the first declaration, and an /* 2 */ in front of all lines
that belong to the scope of the second declaration:

static int bar; /* first declaration of `bar' */
/* 1 */
/* 1 */ void f1(void) {
/* 1 */ bar;
/* 1 */ }
/* 1 */
int bar; /* second declaration of `bar' */
/* 2 */
/* 2 */ void f2(void) {
/* 2 */ bar;
/* 2 */ }


<snip>

I think your problem is in not understanding scopes properly. The above
example should read (using your notation):

static int bar; /* first declaration of `bar' */
/* 1 */
/* 1 */ void f1(void) {
/* 1 */ bar;
/* 1 */ }
/* 1 */
/* 1 */ int bar; /* second declaration of `bar' */ /* BANG! */
/* 1 */
/* 1 */ void f2(void) {
/* 1 */ bar;
/* 1 */ }

As file scope spans the whole of the file (hence the name).

Functions `f1()` and `f2()` have inner scopes of their own, where you
can declare `bar` again, but that `bar` then is local to the function,
and masks the file scope one from the line where it's declared till the
closing brace of the function.

Apr 18 '06 #5
Vladimir S. Oka ha scritto:
I think your problem is in not understanding scopes properly. The above
example should read (using your notation):

static int bar; /* first declaration of `bar' */
/* 1 */
/* 1 */ void f1(void) {
/* 1 */ bar;
/* 1 */ }
/* 1 */
/* 1 */ int bar; /* second declaration of `bar' */ /* BANG! */
/* 1 */
/* 1 */ void f2(void) {
/* 1 */ bar;
/* 1 */ }

As file scope spans the whole of the file (hence the name).


did you mean perhaps something as:

static int bar; /* first declaration of `bar' */
/* 1 */
/* 1 */ void f1(void) {
/* 1 */ bar;
/* 1 */ }
/* 1 */
/* 1 */ int bar; /* second declaration of `bar' */
/* 1 */ /* 2 */
/* 1 */ /* 2 */ void f2(void) {
/* 1 */ /* 2 */ bar;
/* 1 */ /* 2 */ }

?

with the previous notation i mean: the scope of the first declaration
overlaps with the scope of the second declaration from line 8 to line
11, and the second declaration "masks" the first declaration from line 8
to line 11.
Apr 18 '06 #6

fctk wrote:
Vladimir S. Oka ha scritto:
I think your problem is in not understanding scopes properly. The above
example should read (using your notation):

static int bar; /* first declaration of `bar' */
/* 1 */
/* 1 */ void f1(void) {
/* 1 */ bar;
/* 1 */ }
/* 1 */
/* 1 */ int bar; /* second declaration of `bar' */ /* BANG! */
/* 1 */
/* 1 */ void f2(void) {
/* 1 */ bar;
/* 1 */ }

As file scope spans the whole of the file (hence the name).


did you mean perhaps something as:

static int bar; /* first declaration of `bar' */
/* 1 */
/* 1 */ void f1(void) {
/* 1 */ bar;
/* 1 */ }
/* 1 */
/* 1 */ int bar; /* second declaration of `bar' */
/* 1 */ /* 2 */
/* 1 */ /* 2 */ void f2(void) {
/* 1 */ /* 2 */ bar;
/* 1 */ /* 2 */ }

?

with the previous notation i mean: the scope of the first declaration
overlaps with the scope of the second declaration from line 8 to line
11, and the second declaration "masks" the first declaration from line 8
to line 11.


Yes, but you can't have the above. The second declaration is illegal.
That's why I did not include /* 2 */ in my example (I've added a /*
BANG! */, though).

Apr 18 '06 #7
Vladimir S. Oka ha scritto:
fctk wrote:

did you mean perhaps something as:

static int bar; /* first declaration of `bar' */
/* 1 */
/* 1 */ void f1(void) {
/* 1 */ bar;
/* 1 */ }
/* 1 */
/* 1 */ int bar; /* second declaration of `bar' */
/* 1 */ /* 2 */
/* 1 */ /* 2 */ void f2(void) {
/* 1 */ /* 2 */ bar;
/* 1 */ /* 2 */ }

?

with the previous notation i mean: the scope of the first declaration
overlaps with the scope of the second declaration from line 8 to line
11, and the second declaration "masks" the first declaration from line 8
to line 11.

Yes, but you can't have the above. The second declaration is illegal.
That's why I did not include /* 2 */ in my example (I've added a /*
BANG! */, though).


ok, now i think i understand why the second instance of `bar' in my
example has both internal and external linkage.

anyway i don't understand why the following piece of code (without f1
and f2 functions) is wrong:

static int bar;
int bar;

the previous gets re-written as:

static int bar; /* first declaration of identifier `bar' */
/* 1 */
/* 1 */ int bar; /* second declaration of identifier `bar' */
/* 1 */ /* 2 */

there is *no* instance of identifier `bar' in the scope of some
declaration. so it is false that there is an instance of `bar' with both
external and internal linkage.

when trying to compile, i get:

error: non-static declaration of 'bar' follows static declaration
error: previous declaration of 'bar' was here

i'm sure there is something else i haven't fully understood yet.
Apr 18 '06 #8

fctk wrote:
Vladimir S. Oka ha scritto:
fctk wrote:

did you mean perhaps something as:

static int bar; /* first declaration of `bar' */
/* 1 */
/* 1 */ void f1(void) {
/* 1 */ bar;
/* 1 */ }
/* 1 */
/* 1 */ int bar; /* second declaration of `bar' */
/* 1 */ /* 2 */
/* 1 */ /* 2 */ void f2(void) {
/* 1 */ /* 2 */ bar;
/* 1 */ /* 2 */ }

?

with the previous notation i mean: the scope of the first declaration
overlaps with the scope of the second declaration from line 8 to line
11, and the second declaration "masks" the first declaration from line 8
to line 11.

Yes, but you can't have the above. The second declaration is illegal.
That's why I did not include /* 2 */ in my example (I've added a /*
BANG! */, though).


ok, now i think i understand why the second instance of `bar' in my
example has both internal and external linkage.

anyway i don't understand why the following piece of code (without f1
and f2 functions) is wrong:

static int bar;
int bar;

the previous gets re-written as:

static int bar; /* first declaration of identifier `bar' */
/* 1 */
/* 1 */ int bar; /* second declaration of identifier `bar' */
/* 1 */ /* 2 */

there is *no* instance of identifier `bar' in the scope of some
declaration. so it is false that there is an instance of `bar' with both
external and internal linkage.

when trying to compile, i get:

error: non-static declaration of 'bar' follows static declaration
error: previous declaration of 'bar' was here

i'm sure there is something else i haven't fully understood yet.


Maybe you should try thinking about this particular example in this
way:

static int bar;

Tells the compiler that `bar` is "visible" only internally to the file
in question.

int bar;

Then tells the compiler that it is "visible" externally as well.

Logically, both can't be true at the same time, hence the error.

Apr 18 '06 #9
Vladimir S. Oka ha scritto:
Maybe you should try thinking about this particular example in this
way:

static int bar;

Tells the compiler that `bar` is "visible" only internally to the file
in question.

int bar;

Then tells the compiler that it is "visible" externally as well.

Logically, both can't be true at the same time, hence the error.


mmh... but i think there is another error. `static int bar' and `int
bar' are two *definitions* other than two declarations. they are two
definitions of the *same* object.

it is as if i wrote:

static void f1(void) {}
extern void f1(void) {}

isn't it?
Apr 18 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
2795
by: Web Developer | last post by:
Hi, I read that identifiers should not start with an underscore in order to prevent LINKAGE problems. I am not familar with this concept of "linkage", so can someone provide a simple explanation? Thanks in advance WD
9
12144
by: qazmlp | last post by:
const has internal linkage in C++, but external linkage in C. Am I right ? But, linker reports multiply-defined error if the following header is included in multiple .cpp files. // test_const.h #ifndef HEADER_TEST #define HEADER_TEST
47
3885
by: Richard Hayden | last post by:
Hi, I have the following code: /******************************** file1.c #include <iostream> extern void dummy(); inline int testfunc() {
20
3154
by: Grumble | last post by:
Hello everyone, As far as I understand, the 'inline' keyword is a hint for the compiler to consider the function in question as a candidate for inlining, yes? What happens when a function with extern linkage is inlined? Should the compiler still export the function? Or is an inlined function implicitly static?
10
6198
by: Mark A. Gibbs | last post by:
I have a question about mixing C and C++. In a C++ translation unit, I want to define a function with internal linkage and C calling convention. Here's a sample of what I want to do: // main.cpp // This is defined in a C module extern "C" void fake_qsort(void*, std::size_t, std::size_t, int (*compare)(const void*, const void*));
4
1132
by: project | last post by:
Anybody can solve following doubts? 1. Normalization rules. 2. Garbage Collection 3.LinkList Posted Via Usenet.com Premium Usenet Newsgroup Services ---------------------------------------------------------- ** SPEED ** RETENTION ** COMPLETION ** ANONYMITY ** ----------------------------------------------------------
3
6036
by: al.cpwn | last post by:
do static and inline functions or members have internal linkage? I have been reading this newsgroup on google and found conflicting ideas. Can someone please help me understand why in some places inline may have external linkage while in others it has internal (from what I have read in comments by people). Are there any (other) places where linkage is ambiguous?
3
13256
by: Rahul Babbar | last post by:
Hi, I had the following doubts about the "For Read Only" clause. 1. How does a "for Read only" clause improve the performance? 2. How does a "for Read only" clause compare with "With UR" clause in performance? Which is faster? Can someone clarify on that?
1
3760
by: Giacomo Catenazzi | last post by:
Hello, To learn the details of C, I've build the following example, could you check if it is correct and if it miss some important cases? Are there some useful (real cases) examples of: - "function prototype scope" for structures and unions? - "extern" for internal linkage ?
0
9474
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10306
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10138
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
6724
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5373
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5503
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4037
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3632
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2869
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.