473,320 Members | 2,020 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,320 software developers and data experts.

Help wanted on some source codes

1.===========================================
/* a.c */
int x;
int y;

void main()
{
f();
printf("%x %x\n", x, y);
}

/* b.c */
double x;

void f()
{
x = -0.0;
}
2.===========================================
/* a.c */
int x = 1;
int y;

void main()
{
f();
printf("%x %x\n", x, y);
}

/* b.c */
double x;

void f()
{
x = -0.0;
}

3.===========================================
/* a.c */
int x;
int y = 1;

void main()
{
f();
printf("%x %x\n", x, y);
}

/* b.c */
double x;

void f()
{
x = -0.0;
}

4.===========================================
/* a.c */
int x = 1;
int y = 1;

void main()
{
f();
printf("%x %x\n", x, y);
}

/* b.c */
double x;

void f()
{
x = -0.0;
}

5.===========================================
/* a.c */
int x = 1;
int y = 1;

void main()
{
f();
printf("%x %x\n", x, y);
}

/* b.c */
double x;

void f()
{
x = -0;
}
Remark=======================================
The above programs from 1 to 5 are all constituted
of two separate files, a.c & b.c, and can be
compiled under gcc.
e.g.
/* Linux */
$ gcc -o test a.c b.c
$ ./test
/* Windows */
C:\gcc -o test.exe a.c b.c
C:\test
Question=======================================
I'm wondering about the strange results generated
by the programs. Please help me. I want to understand
why the results are like that.
By the way, the source codes above are in old K&R style
and will be warned by the gcc, you can change them to
new ISO/ANSI style :-)

Thanks in advance & best regards!

Becker
30-Nov-2005

Nov 30 '05 #1
13 1224
In article <11**********************@z14g2000cwz.googlegroups .com>,
Becker <we*******@devhr.com> wrote:
1.===========================================
/* a.c */
int x;
int y;

void main()
{
f();
printf("%x %x\n", x, y);
}
%x expects an unsigned int, not an int.
/* b.c */
double x;

void f()
{
x = -0.0;
}
You never initialize y at all, and you initialize x to the wrong
type. double might or might not be the same size as int; it is not
uncommon for it to be longer, but that is not certain. If it is longer
then you -might- end up overwritting y, but the relative order of x and
y are not fixed by the standard, and double might be larger than two
ints together so you might be scribbling on a random portion of memory.

If you happen to be using IEEE754 floating point, then -0.0 is
considered to be different than 0.0 . Even on systems that it is not,
the floating point representation of 0 is not certain to be all binary
0's (though -some- floating point standards require that all-binary 0's
must be treated as floating point 0.)

Your programs 2 thru 4 are just variations on exactly the same themes
with various different values initializing the memory that might or might
not be scribbled over.

5.=========================================== void f()
{
x = -0;
}


-0 is an integer constant, and it is the same as 0 on all but the
rather-uncommon signed-magnitude machines (which are allowed for by
the standard.) -0 as an integer is thus the same as 0 as an integer.
That integer is then cast to the double that you have declared x to
be in this file. On some systems that is different than the floating
point -0.0 .
--
"It is important to remember that when it comes to law, computers
never make copies, only human beings make copies. Computers are given
commands, not permission. Only people can be given permission."
-- Brad Templeton
Nov 30 '05 #2
Becker wrote:
1.===========================================
/* a.c */
int x;
int y;

void main()
{
f();
printf("%x %x\n", x, y);
}

/* b.c */
double x;

void f()
{
x = -0.0;
}


All of your programs have undefined behaviour because there
are two variables called 'x' with external linkage.

Also, "%x" is only to be used for unsigned ints, and
main should return an int (allowing "void main" is compiler-
specific).

For an understanding of why GCC gives the results you see,
please ask your question on a GCC newsgroup.

Nov 30 '05 #3
Old Wolf wrote:
Becker wrote:
1.===========================================
/* a.c */
int x;
int y;

void main()
{
f();
printf("%x %x\n", x, y);
}

/* b.c */
double x;

void f()
{
x = -0.0;
}


All of your programs have undefined behaviour because there
are two variables called 'x' with external linkage.


The programs are rubbish of course. But wouldn't the file scope of x
mean that function f() is actually refering to the double x instead of
the int x?

Nov 30 '05 #4
On 29 Nov 2005 16:45:47 -0800, "Becker" <we*******@devhr.com> wrote in
comp.lang.c:
1.===========================================
/* a.c */
int x;
int y;

void main()
{
f();
printf("%x %x\n", x, y);
}

/* b.c */
double x;

void f()
{
x = -0.0;
}


[snip several other examples]

Each of your examples defines main() with a return type of void, and
also has main() call a function without a declaration in scope. There
is no version of the C standard where a program performing both of
these actions is legal.

If you are using gcc as a standard compiler conforming to the C
standard prior to 1999, 'void main()' invokes undefined behavior
immediately. Friends don't let friends void main(). If you are using
gcc as a standard compiler conforming to a 1999 or later version of
the C standard, it is a constraint violation to call a function
without a declaration in scope.

So you are not invoking gcc to conform to any version of the C
standard, which is just as well, because your program is not actually
valid C.

But as to the question you asked, even if you fixed these things:

Each of your examples defines 'x' with external linkage in two
different source files. It doesn't even make any difference whether
'x' has the same type or different types in the two definitions, you
have broken a rule and have undefined behavior.

Once you have undefined behavior, it's "game over, thanks for playing,
Carol will give you some lovely parting gifts". The C language
neither knows or cares what happens next, there is no right or wrong.
It could cause the CD drive tray to jump out and hit you in the nose.
Even if the computer does not have a CD drive.

The C standard says this in "6.9 External definitions" paragraph 5:

"An external definition is an external declaration that is also a
definition of a function (other than an inline definition) or an
object. 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."

--
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++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 30 '05 #5
On 29 Nov 2005 18:34:15 -0800, "sl*******@yahoo.com"
<sl*******@gmail.com> wrote in comp.lang.c:
Old Wolf wrote:
Becker wrote:
1.===========================================
/* a.c */
int x;
int y;

void main()
{
f();
printf("%x %x\n", x, y);
}

/* b.c */
double x;

void f()
{
x = -0.0;
}


All of your programs have undefined behaviour because there
are two variables called 'x' with external linkage.


The programs are rubbish of course. But wouldn't the file scope of x
mean that function f() is actually refering to the double x instead of
the int x?


This is part of what I posted in a reply to the OP, but I'll repeat it
here for your benefit. The issue here is NOT file scope, but most
specifically IS external linkage:

The C standard says this in "6.9 External definitions" paragraph 5:

"An external definition is an external declaration that is also a
definition of a function (other than an inline definition) or an
object. 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."

Violating a 'shall' outside of a constraint section is just plain old
ordinary undefined behavior. You have left planet C behind and
entered the Twilight Zone, and there is no right or wrong.

--
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++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html

--
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++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 30 '05 #6
sl*******@yahoo.com wrote:
Old Wolf wrote:
Becker wrote:
1.===========================================
/* a.c */
int x;
int y;

void main()
{
f();
printf("%x %x\n", x, y);
}

/* b.c */
double x;

void f()
{
x = -0.0;
}

All of your programs have undefined behaviour because there
are two variables called 'x' with external linkage.


The programs are rubbish of course. But wouldn't the file scope of x
mean that function f() is actually refering to the double x instead of
the int x?

Nope, because technically, there's no difference between the two.

First of all, this program is in violation of:

6.9-5 "If an identifier declared with external linkage is used in an
expression [..], somewhere in the entire program there shall be exactly one
external definition for the identifier; [..]"

But suppose one of these was an "extern" declaration instead, so there was
only one definition. Then we get:

6.2.2-2 "In the set of translation units and libraries that constitutes an
entire program, each declaration of a particular identifier with external
linkage denotes the same object or function."

So the "int x" and "double x" must be the same object. But of course that's
not possible, and we are violating:

6.2.7-2 "All declarations that refer to the same object or function shall
have compatible type; otherwise, the behavior is undefined."

Needless to say, int and double are not compatible types.

Now, in *practice*, a compiler will indeed treat the 'x' in a.c and the 'x'
in b.c as different objects within their respective scopes, compile the
units as such, and then the linker will either notice a conflict (best
case), create two separate objects (suboptimal but not completely awful
case), or not notice anything at all and happily merge the storage for these
incompatible objects (worst but unfortunately also most likely case).

Try this: assign some nontrivial value to 'x' in 'f', try to compile and
link the program, then run it if this works. You should see the value of the
double (partially) reinterpreted as an int. Say hi to the nasal demons for
me when you do this.

This notwithstanding, a platform would actually be allowed to format your
harddisk immediately after parsing both a.c and b.c, without paying any
consideration to scope. The behavior is undefined; scope is irrelevant.

S.
Nov 30 '05 #7
Jack Klein wrote:
On 29 Nov 2005 18:34:15 -0800, "sl*******@yahoo.com"
<sl*******@gmail.com> wrote in comp.lang.c:
The programs are rubbish of course. But wouldn't the file scope of x
mean that function f() is actually refering to the double x instead of
the int x?


This is part of what I posted in a reply to the OP, but I'll repeat it
here for your benefit. The issue here is NOT file scope, but most
specifically IS external linkage:

The C standard says this in "6.9 External definitions" paragraph 5:

"An external definition is an external declaration that is also a
definition of a function (other than an inline definition) or an
object. 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."

Violating a 'shall' outside of a constraint section is just plain old
ordinary undefined behavior. You have left planet C behind and
entered the Twilight Zone, and there is no right or wrong.


Yes I understand that. But I didn't think all globals are external
linkage by default. I thought you need to use the 'extern' keyword for
that. So, without extern globals with the same name have undefined
behavior? I'm guessing that globals declared with the 'static' keyword
can have the same name.

Nov 30 '05 #8
sl*******@yahoo.com said:
But I didn't think all globals are external
linkage by default. I thought you need to use the 'extern' keyword for
that.


No. When you do this:

extern int foo;

you are saying "dear compiler, I promise to you that there is an object
called foo, which is an int, but its storage is already reserved elsewhere
so you don't need to reserve any; just trust me on this". Each translation
unit needing to read or write foo (EXCEPT ONE) will need to have such a
line. Typically, such lines are put into a header.

In exactly one place in your program (at file scope), you must keep your
promise:

int foo;

The translation unit that has this line need not have an extern int foo; as
well (although it will do no harm if it does).

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Nov 30 '05 #9
Richard Heathfield wrote:
sl*******@yahoo.com said:
But I didn't think all globals are external
linkage by default. I thought you need to use the 'extern' keyword for
that.


No. When you do this:

extern int foo;

you are saying "dear compiler, I promise to you that there is an object
called foo, which is an int, but its storage is already reserved elsewhere
so you don't need to reserve any; just trust me on this". Each translation
unit needing to read or write foo (EXCEPT ONE) will need to have such a
line. Typically, such lines are put into a header.

In exactly one place in your program (at file scope), you must keep your
promise:

int foo;

The translation unit that has this line need not have an extern int foo; as
well (although it will do no harm if it does).


Ah yes, quite right. Extern merely means "it's somewhere else" not
"please export this". Thank you for reminding me.

Nov 30 '05 #10
Thanks all :-)
Yes, I understand now. The codes are full of undifined behaviors.
And If I want to know why the results are like that, I should
get to know how gcc treats those "undifined behaviors".

PS: I get those programs from a forum :-P

Nov 30 '05 #11
Jack Klein wrote:
Friends don't let friends void main().


I like it! Looks like sig material to me.

Allin Cottrell
Nov 30 '05 #12
sl*******@yahoo.com wrote:
Old Wolf wrote:
Becker wrote:
1.===========================================
/* a.c */
int x;
int y;

void main()
{
f();
printf("%x %x\n", x, y);
}

/* b.c */
double x;

void f()
{
x = -0.0;
}

All of your programs have undefined behaviour because there
are two variables called 'x' with external linkage.


The programs are rubbish of course. But wouldn't the file scope of x
mean that function f() is actually refering to the double x instead of
the int x?


No, both variable x have external linkage therefore the behaviour is
undefined and on some systems, with some options, won't even link. If it
does link the compiler is allowed to put both items in the same
location, make that location the size of the smaller (probably int) and
send a letter to you mother telling her you are dead. Alternatively the
compiler/linker could place the two variables in separate locations and
send a letter to the accounts department of the company you work for
telling them to stop your salary. Anything it does is valid.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 30 '05 #13

Flash Gordon wrote:

No, both variable x have external linkage therefore the behaviour is
undefined and on some systems, with some options, won't even link. If it
does link the compiler is allowed to put both items in the same
location, make that location the size of the smaller (probably int) and
send a letter to you mother telling her you are dead. Alternatively the
compiler/linker could place the two variables in separate locations and
send a letter to the accounts department of the company you work for
telling them to stop your salary. Anything it does is valid.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.


hehe, I got it.

Nov 30 '05 #14

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

Similar topics

8
by: Howard | last post by:
My friend is seeking help with some homework writting javascript. Please respond to here address at ghina@hotmail.com Thanks for your help in advance. Write java statement to perform the...
9
by: YZK | last post by:
Hello. I'm not a Web developer, just a user, and I think I may have somehow messed myself up majorly. I'm not quite sure how. Right now, javascript used by websites I go to either does not work at...
2
by: Thames | last post by:
Hi, I have to repost my question for help. Yesterday I set up two DB UDB ESE V8.2 server on linux and windows platform, respectively. Both servers have been connected without any problems...
1
by: PerryC | last post by:
Can someone help me accomplish the following in a MSAccess Report: 1. Check if Me.Discipline = "RN" (within the source query) 2. Then check the Me.YearOfEmployment: (again within the same source...
13
by: Brett Baisley | last post by:
At school, we do all of our coding in emacs, but I am trying to get the example apps working at home using Visual C++.net. In the example, there are 4 .cpp files (canvas.cpp, main.cpp,...
11
by: Jim S. | last post by:
hi guys and gals, i have an array, but i have the hardest time putting the value in the table, so what is the normal procedure? thanks Jim
1
by: Rahul | last post by:
Hi Everybody I have some problem in my script. please help me. This is script file. I have one *.inq file. I want run this script in XML files. But this script errors shows . If u want i am...
2
by: lovesehuang | last post by:
need some help for source codes about Keep Data Secret Management System baseed on C/S Architecture.The other thnics we need is SQL,C++,VC++,can u tell me where can i get them or download them.it's...
0
by: gunimpi | last post by:
http://www.vbforums.com/showthread.php?p=2745431#post2745431 ******************************************************** VB6 OR VBA & Webbrowser DOM Tiny $50 Mini Project Programmer help wanted...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

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.