473,398 Members | 2,812 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

External object definitions

Hi to all,

To explain my question I'll help myself
with the following two code snippets:

/*** file1.c ***/

#include <stdio.h>

void print_it(void);
int i;

int main(void)
{
print_it();
printf("main i = %d\n", i);

return 0;
}

/*** file2.c ***/

#include <stdio.h>

int i;

void print_it(void)
{
i = 2;
printf("print_it i = %d\n", i);
}
As you can see I have a
tentative definition for object `i',
in both TUs.
According to C99 6.9.2 p2, one can deduce
that both of these tentative definitions, will
turn into real definitions at the end of the
TUs with initializer zero.

Then I think that in this case I will be having,
*two definitions* for the same identifier with
external linkage!
Then I would be violating a semantics constraint.
Specifically the one pointed out in C99 6.9 p5.

To my surprise, I didn't receive any diagnostics
from the compiler. I compiled this program using
this command line:

$ gcc -g -Wall -ansi -pedantic -o filex file1.c file2.c

I even ran the executable generated, and it ran OK:
$ filex
print_it i = 2
main i = 2

What am I getting wrong?
What is my error?
What am I misunderstanding here?

Thank you very much in advance,

Max
Nov 13 '05 #1
9 4174
maxw_cc wrote:
Then I think that in this case I will be having,
*two definitions* for the same identifier with
external linkage!


No, the two identifiers designate the same object.
Default initialization is for the object, not for
each designation.

Nov 13 '05 #2
On 12 Aug 2003 23:50:28 -0700, ma*****@yahoo.com (maxw_cc) wrote in
comp.lang.c:
Hi to all,

To explain my question I'll help myself
with the following two code snippets:

/*** file1.c ***/

#include <stdio.h>

void print_it(void);
int i;

int main(void)
{
print_it();
printf("main i = %d\n", i);

return 0;
}

/*** file2.c ***/

#include <stdio.h>

int i;

void print_it(void)
{
i = 2;
printf("print_it i = %d\n", i);
}
As you can see I have a
tentative definition for object `i',
in both TUs.
According to C99 6.9.2 p2, one can deduce
that both of these tentative definitions, will
turn into real definitions at the end of the
TUs with initializer zero.

Then I think that in this case I will be having,
*two definitions* for the same identifier with
external linkage!
Then I would be violating a semantics constraint.
Specifically the one pointed out in C99 6.9 p5.
There is no such thing as a "semantics constraint". The constraints
in 6.9 are paragraphs 2 and 3. Paragraphs 4 and 5 are in the
semantics section, and are not constraints.
To my surprise, I didn't receive any diagnostics
from the compiler. I compiled this program using
this command line:
The compiler by definition deals with one translation unit at a time.
$ gcc -g -Wall -ansi -pedantic -o filex file1.c file2.c

I even ran the executable generated, and it ran OK:
$ filex
print_it i = 2
main i = 2

What am I getting wrong?
What is my error?
What am I misunderstanding here?

Thank you very much in advance,

Max


When your separately compiled translation units are linked together by
your linker, you are indeed violating the terms of 6.9 p5.

Specifically the wording "If an identifier declared with external
linkage is used in an expression (other than as part of the operand of
a sizeof operator whose result is an integer constant), somewhere in
the entire program there shall be exactly one external definition for
the identifier; otherwise, there shall be no more than one."

But this is not a constraint violation, because it is not in a
constraints section, but a semantics one.

So what applies here is p2 of section 4:

"If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a
constraint is violated, the behavior is undefined."

Your program invokes undefined behavior, which requires neither a
diagnostic nor any particular results, as far as the standard is
concerned.

Different languages have different conceptual models of what C calls
external linkage. Some of them require the behavior that you see,
where there can be multiple definitions of an external symbol so long
as no more than one of them contain an initializer. FORTRAN named
common blocks need this, for example. So the linkers of some tools
work this way. Essentially they pass the concept of tentative
definition on to the linker.

C allows but does not require this feature by making the results of
such a program undefined.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
Nov 13 '05 #3
ma*****@yahoo.com (maxw_cc) wrote:

As you can see I have a
tentative definition for object `i',
in both TUs.
According to C99 6.9.2 p2, one can deduce
that both of these tentative definitions, will
turn into real definitions at the end of the
TUs with initializer zero.

Then I think that in this case I will be having,
*two definitions* for the same identifier with
external linkage!
Then I would be violating a semantics constraint.
Specifically the one pointed out in C99 6.9 p5.
As explained in another followup, this results in undefined behaviour.
To my surprise, I didn't receive any diagnostics
from the compiler.


This is one of the "common implementation extensions", see J.5.11
"multiple external definitions":

[#1] There may be more than one external definition for the
identifier of an object, with or without the explicit use of
the keyword extern; if the definitions disagree, or more
than one is initialized, the behavior is undefined (6.9.2).

Tony.
--
f.a.n.finch <do*@dotat.at> http://dotat.at/
FAIR ISLE: VARIABLE BECOMING NORTHWESTERLY 3 OR 4 INCREASING 5 TO 7. RAIN THEN
SQUALLY SHOWERS. MODERATE BECOMING GOOD.
Nov 13 '05 #4
In message <Q9********************@comcast.com>, Douglas A. Gwyn
<DA****@null.net> writes
maxw_cc wrote:
Then I think that in this case I will be having,
*two definitions* for the same identifier with
external linkage!


No, the two identifiers designate the same object.
Default initialization is for the object, not for
each designation.


This is one of the areas of C that has always left me deeply
uncomfortable. As I understand it, the programmer who decides to provide
explicit initialisation transforms the two declarations into two
distinct objects. I have always thought that the idea is deeply flawed.
It breaks the general description that variables are, by default,
defined and pure declarations need to be made using extern.
--
ACCU Spring Conference 2003 April 2-5
The Conference you should not have missed
ACCU Spring Conference 2004 Late April
Francis Glassborow ACCU

Nov 13 '05 #5
In <bh**********@news-reader5.wanadoo.fr> "jacob navia" <ja*********@jacob.remcomp.fr> writes:
When I wrote the linker of lcc-win32 I was confronted to this problem.
All linkers have this quite uncredible behavior:

File1.c
int table[2];

File2.c
int table[834];
int main(void { }

This will link without any warnings, even with

gcc -pedantic f1.c 2.c
It's undefined behaviour, so why do you expect a diagnostic? Besides,
-pedantic has nothing to do with the linking stage.
In my linker, I added a warning, but still left this as is. I am still wandering
why this behavior is continued.

Should I discontinue this? Should I give an error rather than just
a warning???
The C standard is giving you free hand. A diagnostic is certainly
helpful, it doesn't really matter whether it's an error or a warning
(any user ignoring such a warning gets exactly what he deserves).
P.S. All this happens only with bss variables of course. If you mix
bss with initialized data variables the behavior is even stranger!


Undefined behaviour can never be too strange ;-)

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #6
jacob navia a écrit :
When I wrote the linker of lcc-win32 I was confronted to this problem.
All linkers have this quite uncredible behavior:

File1.c
int table[2];

File2.c
int table[834];
int main(void { }

This will link without any warnings, even with

gcc -pedantic f1.c 2.c
-Wl,--warn-common is the option that gives a warning with gcc, for this kind
of code.
In my linker, I added a warning, but still left this as is. I am still
wandering why this behavior is continued.


It seems to be a common practice in the unix world. According to ld manual :
--warn-common
Warn when a common symbol is combined with another common symbol
or with a symbol definition. Unix linkers allow this somewhat
sloppy practice, but linkers on some other operating systems do
not. This option allows you to find potential problems from com-
bining global symbols. Unfortunately, some C libraries use this
practice, so you may get some warnings about symbols in the
libraries as well as in your programs.

--
Richard
Nov 13 '05 #7
Richard Delorme <ab****@nospam.fr> writes:

|> jacob navia a écrit :
|>
|> > When I wrote the linker of lcc-win32 I was confronted to this problem.
|> > All linkers have this quite uncredible behavior:
|> >
|> > File1.c
|> > int table[2];
|> >
|> > File2.c
|> > int table[834];
|> > int main(void { }
|> >
|> > This will link without any warnings, even with
|> >
|> > gcc -pedantic f1.c 2.c
|>
|> -Wl,--warn-common is the option that gives a warning with gcc, for this kind
|> of code.

Another option is to compile with -fno-common, which will cause the
linker to error out on the multiple definitions of table.

Andreas.

--
Andreas Schwab, SuSE Labs, sc****@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
Nov 13 '05 #8
Tony Finch <do*@dotat.at> wrote in message news:<Vo*******@news.chiark.greenend.org.uk>...
This is one of the "common implementation extensions", see J.5.11
"multiple external definitions":

[#1] There may be more than one external definition for the
identifier of an object, with or without the explicit use of
the keyword extern; if the definitions disagree, or more
than one is initialized, the behavior is undefined (6.9.2).

Tony.

First of all thanks to all of you for your good inputs.
Especially thank you very much to Jack Klein and Tony
Finch, you've been of great help.

However, I still wonder why they put 6.9.2 in the last
sentence of J.5.11 p1. I see this as if they were telling me
to look at 6.9.2 to find justifications on why having discrepant
definitions or having multiple external definitions (not tentative)
invoke UB. It would have made more sense to me if they
had put 6.9 and/or probably 6.2.2.

Thanks again for all your help,

Max
Nov 13 '05 #9
In article <bh**********@news-reader5.wanadoo.fr>, jacob navia
<ja*********@jacob.remcomp.fr> writes
When I wrote the linker of lcc-win32 I was confronted to this problem.
All linkers have this quite uncredible behavior:

File1.c
int table[2];

File2.c
int table[834];
int main(void { }

This will link without any warnings, even with

gcc -pedantic f1.c 2.c


This dates back to early versions of Fortran (my X3.9-1966 isn't to
hand, so I can't say if it was standardised or not), where you could
write:

COMMON /TABLE/ T(2)

in one subroutine and:

COMMON /TABLE/ T(834)

in another. The linker would assign enough memory for the largest
version of each common block.

--
Clive D.W. Feather, writing for himself | Home: <cl***@davros.org>
Tel: +44 20 8371 1138 (work) | Web: <http://www.davros.org>
Fax: +44 870 051 9937 | Work: <cl***@demon.net>
Written on my laptop; please observe the Reply-To address
Nov 13 '05 #10

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

Similar topics

0
by: Putz Ronald | last post by:
Hy! I am trying to convert a win Oracle application to solaris! We have use external c functions which I have ibncluded in a shared object. See the makefile below: OBJECTS = definitions.o...
6
by: Christopher Benson-Manica | last post by:
Just FMI, if an external stylesheet is linked to a page (with <link>), will subsequent <style> tags override the values in the external stylesheet? -- Christopher Benson-Manica | I *should*...
6
by: Adam Bozanich | last post by:
Hi all. I am porting a C program I wrote to C++. I am having some issues with external variables. In C, I can have global variables declared in common header files, but I get "multiple...
47
by: Richard Hayden | last post by:
Hi, I have the following code: /******************************** file1.c #include <iostream> extern void dummy(); inline int testfunc() {
19
by: J. J. Farrell | last post by:
After many years of dealing with definition and linkage issues in ways that I know to be safe, I've decided it's time to try to understand this area properly. Consider a header file with the file...
4
by: Peter Ammon | last post by:
I would like to share a variable between two functions defined in two separate source files; no other functions will need the global variable so I'd prefer to not give it file scope. Thus, I want...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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...
0
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...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.