Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Why no compilation error.

Reply
Thread Tools

Why no compilation error.

 
 
sunny
Guest
Posts: n/a
 
      09-20-2006
We have three files a.c, b.c and main.c respectively as follows:
a.c
---
int a;
b.c
---
int a = 10;
main.c
------
extern int a;
int main()
{
printf("a = %d\n",a);
return 0;
}
Let's see what happens, when the files are compiled together:
bash$ gcc a.c b.c main.c
bash$ ./a.out
a = 10
Hmm!! no compilation/linker error!!! Why is it so??

 
Reply With Quote
 
 
 
 
Jack Klein
Guest
Posts: n/a
 
      09-20-2006
On 19 Sep 2006 22:12:12 -0700, "sunny" <(E-Mail Removed)> wrote in
comp.lang.c:

> We have three files a.c, b.c and main.c respectively as follows:
> a.c
> ---
> int a;
> b.c
> ---
> int a = 10;
> main.c
> ------
> extern int a;
> int main()
> {
> printf("a = %d\n",a);
> return 0;
> }
> Let's see what happens, when the files are compiled together:
> bash$ gcc a.c b.c main.c
> bash$ ./a.out
> a = 10
> Hmm!! no compilation/linker error!!! Why is it so??


Your program produces undefined behavior by having more than one
definition of an external object. The compiler is free to do anything
it wants. Once you generate undefined behavior, the C language no
longer places any requirements on the results.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
 
Reply With Quote
 
 
 
 
deepak
Guest
Posts: n/a
 
      09-20-2006
Can anyone give a nice link of how these example works?

Jack Klein wrote:
> On 19 Sep 2006 22:12:12 -0700, "sunny" <(E-Mail Removed)> wrote in
> comp.lang.c:
>
> > We have three files a.c, b.c and main.c respectively as follows:
> > a.c
> > ---
> > int a;
> > b.c
> > ---
> > int a = 10;
> > main.c
> > ------
> > extern int a;
> > int main()
> > {
> > printf("a = %d\n",a);
> > return 0;
> > }
> > Let's see what happens, when the files are compiled together:
> > bash$ gcc a.c b.c main.c
> > bash$ ./a.out
> > a = 10
> > Hmm!! no compilation/linker error!!! Why is it so??

>
> Your program produces undefined behavior by having more than one
> definition of an external object. The compiler is free to do anything
> it wants. Once you generate undefined behavior, the C language no
> longer places any requirements on the results.
>
> --
> Jack Klein
> Home: http://JK-Technology.Com
> FAQs for
> comp.lang.c http://c-faq.com/
> comp.lang.c++ http://www.parashift.com/c++-faq-lite/
> alt.comp.lang.learn.c-c++
> http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html


 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      09-20-2006
Jack Klein wrote:
> "sunny" <(E-Mail Removed)> wrote in comp.lang.c:
> > We have three files a.c, b.c and main.c respectively as follows:
> > a.c
> > ---
> > int a;
> > b.c
> > ---
> > int a = 10;
> > main.c
> > ------
> > extern int a;
> > int main()
> > {
> > printf("a = %d\n",a);
> > return 0;
> > }
> > Let's see what happens, when the files are compiled together:
> > bash$ gcc a.c b.c main.c


Note: gcc has not been invoked as a conforming compiler, so you
can't have any expectations under the C language standard.

> > bash$ ./a.out
> > a = 10
> > Hmm!! no compilation/linker error!!! Why is it so??

>
> Your program produces undefined behavior by having more than one
> definition of an external object. The compiler is free to do anything
> it wants. Once you generate undefined behavior, the C language no
> longer places any requirements on the results.


Or, to more accurately answer the OP's question, the behaviour is UB
by 6.9p5, however that paragraph is not one of the listed Contraints
for 6.9 [pp2-3], so no diagnostic is required.

Why it's not a constraint, I don't know.

--
Peter

 
Reply With Quote
 
=?utf-8?B?SGFyYWxkIHZhbiBExLNr?=
Guest
Posts: n/a
 
      09-20-2006
Peter Nilsson wrote:
> Jack Klein wrote:
> > "sunny" <(E-Mail Removed)> wrote in comp.lang.c:
> > > We have three files a.c, b.c and main.c respectively as follows:
> > > a.c
> > > ---
> > > int a;
> > > b.c
> > > ---
> > > int a = 10;
> > > main.c
> > > ------
> > > extern int a;
> > > int main()
> > > {
> > > printf("a = %d\n",a);
> > > return 0;
> > > }
> > > Let's see what happens, when the files are compiled together:
> > > bash$ gcc a.c b.c main.c

>
> Note: gcc has not been invoked as a conforming compiler, so you
> can't have any expectations under the C language standard.
>
> > > bash$ ./a.out
> > > a = 10
> > > Hmm!! no compilation/linker error!!! Why is it so??

> >
> > Your program produces undefined behavior by having more than one
> > definition of an external object. The compiler is free to do anything
> > it wants. Once you generate undefined behavior, the C language no
> > longer places any requirements on the results.

>
> Or, to more accurately answer the OP's question, the behaviour is UB
> by 6.9p5, however that paragraph is not one of the listed Contraints
> for 6.9 [pp2-3], so no diagnostic is required.
>
> Why it's not a constraint, I don't know.


I imagine it's not a constraint because depending on the system, it may
not have an easy way to tell this apart from a definition whose name
matches that of a library function provided as an extension. In other
words, it could also generate a diagnostic for this legitimate code:

#include <stdio.h>
void write(char *s) { puts(s); }
int main(void) {
write("Hello, world!");
}

 
Reply With Quote
 
sunny
Guest
Posts: n/a
 
      09-20-2006
Hi All
but i get the compilation error if i initialize the variable "a" in a.c
ie.
// in a.c
int a = 200;

// in b.c
int a = 10.

on compilation, now i got multiple definition error.
may on first i.e uninitialized "a" will be stored in BSS section and
intialized "a" (a = 10) is stored in DS(data segment). so when i
intialize "a" in a.c
it will move to DS where it confilicts with "a" from b.c;

is it correct?

Peter Nilsson wrote:

> Jack Klein wrote:
> > "sunny" <(E-Mail Removed)> wrote in comp.lang.c:
> > > We have three files a.c, b.c and main.c respectively as follows:
> > > a.c
> > > ---
> > > int a;
> > > b.c
> > > ---
> > > int a = 10;
> > > main.c
> > > ------
> > > extern int a;
> > > int main()
> > > {
> > > printf("a = %d\n",a);
> > > return 0;
> > > }
> > > Let's see what happens, when the files are compiled together:
> > > bash$ gcc a.c b.c main.c

>
> Note: gcc has not been invoked as a conforming compiler, so you
> can't have any expectations under the C language standard.
>
> > > bash$ ./a.out
> > > a = 10
> > > Hmm!! no compilation/linker error!!! Why is it so??

> >
> > Your program produces undefined behavior by having more than one
> > definition of an external object. The compiler is free to do anything
> > it wants. Once you generate undefined behavior, the C language no
> > longer places any requirements on the results.

>
> Or, to more accurately answer the OP's question, the behaviour is UB
> by 6.9p5, however that paragraph is not one of the listed Contraints
> for 6.9 [pp2-3], so no diagnostic is required.
>
> Why it's not a constraint, I don't know.
>
> --
> Peter


 
Reply With Quote
 
Jack Klein
Guest
Posts: n/a
 
      09-20-2006
On 19 Sep 2006 23:59:33 -0700, "sunny" <(E-Mail Removed)> wrote in
comp.lang.c:

> Hi All
> but i get the compilation error if i initialize the variable "a" in a.c
> ie.
> // in a.c
> int a = 200;
>
> // in b.c
> int a = 10.
>
> on compilation, now i got multiple definition error.
> may on first i.e uninitialized "a" will be stored in BSS section and
> intialized "a" (a = 10) is stored in DS(data segment). so when i
> intialize "a" in a.c
> it will move to DS where it confilicts with "a" from b.c;
>
> is it correct?


It is not correct. It is not incorrect. Once you produce undefined
behavior, the C standard no longer specifies what the program must do.
As far as the C language is concerned, anything that happens is just
as correct or incorrect as anything else.

You have broken a rule of C programming. Don't do that. Then you
won't have to worry whether what happens is correct.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
 
Reply With Quote
 
Jean-Marc Bourguet
Guest
Posts: n/a
 
      09-20-2006
"sunny" <(E-Mail Removed)> writes:

> We have three files a.c, b.c and main.c respectively as follows:
> a.c
> ---
> int a;
> b.c
> ---
> int a = 10;
> main.c
> ------
> extern int a;
> int main()
> {
> printf("a = %d\n",a);
> return 0;
> }
> Let's see what happens, when the files are compiled together:
> bash$ gcc a.c b.c main.c
> bash$ ./a.out
> a = 10
> Hmm!! no compilation/linker error!!! Why is it so??
>


With gnu linker, use -Wl,--warn-common. That's the (sloppy) common unix
practice.

A+

--
Jean-Marc
 
Reply With Quote
 
Amigo
Guest
Posts: n/a
 
      09-20-2006
The variable is defined / initialised in two separate files. Each of
these C files will be compiled to object code. At the linking phase,
the linker usually has a specific order in which it searches for
external symbols, e.g. start with all the objects/libraries in current
folder in alphabetical order, followed by the so-called default paths
where other libraries and objects may reside. All the linkers I've
used, by default, will stop looking for an external reference if one
has already been found in an object or a library. Therefore, in this
case, it so happened that the linker encountered the definition with
initialisation first, hence the value 10 is displayed at execution. I
suppose a closer investigation of the linker properties would provide a
clear answer to this issue. Changing the initialisation from one file
to the other may exhibit a different behaviour (or at least I expect
to).

Romeo Ghiriti

 
Reply With Quote
 
Amigo
Guest
Posts: n/a
 
      09-20-2006
The variable is defined / initialised in two separate files. Each of
these C files will be compiled to object code. At the linking phase,
the linker usually has a specific order in which it searches for
external symbols, e.g. start with all the objects/libraries in current
folder in alphabetical order, followed by the so-called default paths
where other libraries and objects may reside. All the linkers I've
used, by default, will stop looking for an external reference if one
has already been found in an object or a library. Therefore, in this
case, it so happened that the linker encountered the definition with
initialisation first, hence the value 10 is displayed at execution. I
suppose a closer investigation of the linker properties would provide a
clear answer to this issue. Changing the initialisation from one file
to the other may exhibit a different behaviour (or at least I expect
to).

Romeo Ghiriti

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Compilation error with seperate compilation C__chp C++ 4 02-15-2008 03:57 PM
why why why why why Mr. SweatyFinger ASP .Net 4 12-21-2006 01:15 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
Why compilation error here? Goran C++ 2 09-12-2006 11:02 AM
compilation problem... WHY? Dariusz Plygawko C++ 3 12-03-2003 10:51 AM



Advertisments