Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > why it doesn't work?

Reply
Thread Tools

why it doesn't work?

 
 
junky_fellow@yahoo.co.in
Guest
Posts: n/a
 
      02-15-2010
Guys,

Consider the following two files, files test.c and test1.c

Contents of test1.c are as follows:
---------------------------------------------------

int arr[] = { 0x100, 0x200 };
int main(void)
{
printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
func();
}

Contents of test1.c
------------------------------
extern int *arr;

func()
{
printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
}

The 2 files are compiled without any error, but when I run the
executable generated, it crashes with segmentation fault.

Can someone please explain what is the reason for crash ?

 
Reply With Quote
 
 
 
 
Michael Tsang
Guest
Posts: n/a
 
      02-15-2010
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

> ---------------------------------------------------
>
> int arr[] = { 0x100, 0x200 };
> int main(void)
> {
> printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
> func();
> }
>
> Contents of test1.c
> ------------------------------
> extern int *arr;
>
> func()
> {
> printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
> }
>

Short:
A pointer object is not an array object, they aren't layout-compatible.

Long:
The type of arr in both TU aren't the same. The above arr is of int[2], the
below is of int* . In terms of implementation, let sizeof(int)==4 and
sizeof(int*)==8, and *array* *object* arr in the above TU is stored at
0x12345678. When the TUs are linked together, func() thinks that a *pointer*
*object* is stored at 0x12345678, so, the func() runs, it reads 8 bytes from
0x12345678, that is, assuming little-endian machine, 0x0000020000000100 and
try to dereference that address, of cause, the program crashes.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkt5YbsACgkQm4klUUKw07BrtwCfUOKZXPA932 cL4jgqCP+g+Q6q
UrwAmgIGxnubcQ7K1O21PsmBQX3jt425
=tin7
-----END PGP SIGNATURE-----

 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-15-2010
"(E-Mail Removed)" <(E-Mail Removed)> writes:

> Guys,


....and gals.

> Consider the following two files, files test.c and test1.c
>
> Contents of test1.c are as follows:
> ---------------------------------------------------
>
> int arr[] = { 0x100, 0x200 };
> int main(void)
> {
> printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
> func();
> }
>
> Contents of test1.c
> ------------------------------
> extern int *arr;


In addition to the comments you've already had, if you don't want to
commit yourself to the size, you can declare arr like this:

extern int arr[];

> func()
> {
> printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
> }


If this is C90 you need a return statement in main. If this is C99
you can't have a function with return type declared using implicit
int. Furthermore, both files need #include <stdio.h> and the format
specifier should match the type of the arguments you are printing (x
is for unsigned int).

Some of these are all details, but what do you gain by playing fast a
loose with the compiler? One day, one of these will bite you (but
probably never the last).

> The 2 files are compiled without any error, but when I run the
> executable generated, it crashes with segmentation fault.


You need to turn up the warning level and then some of the matters
I've raised will be warned about. I prefer to be told!

<snip>
--
Ben.
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      02-15-2010
On 2/15/2010 9:47 AM, (E-Mail Removed) wrote:
> Guys,
> [...]


RTFFAQ. Question 6.1, the very first in the "Arrays
and Pointers" section.

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
junky_fellow@yahoo.co.in
Guest
Posts: n/a
 
      02-15-2010
On Feb 15, 7:55*pm, Richard Heathfield <(E-Mail Removed)> wrote:
> (E-Mail Removed) wrote:
> > Guys,

>
> > * *Consider the following two files, files test.c and test1.c

>
> > Contents of test1.c are as follows:
> > ---------------------------------------------------

>
> > int arr[] = { 0x100, *0x200 };
> > int main(void)
> > {
> > * *printf("arr[0]=%x arr[1]=%x\n", arr[0], arr[1]);
> > * *func();
> > }

>
> > Contents of test1.c
> > ------------------------------
> > extern int *arr;

>
> Change this to:
>
> extern int arr[2];
>
> and all will be well.
>
> arr is an array, not a pointer. The difference is important.
>
> <snip>


I understand the difference between the types of "arr" in two files.
What I wanted to know is what the linker did when it encountered
"extern int *arr"?
First of all why it didn't give any error ?
What value it assigned to "arr declared as integer pointer" ?
When I print the value of "arr" (printf("arr=%p", arr)) in test1.c,
value printed was 0x100.

Can you please tell, why the (int *arr) was assigned value 0x100?

 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      02-15-2010
On 2010-02-15, (E-Mail Removed) <(E-Mail Removed)> wrote:
> I understand the difference between the types of "arr" in two files.
> What I wanted to know is what the linker did when it encountered
> "extern int *arr"?


Whatever it wanted?

> First of all why it didn't give any error ?


Why should it have?

> What value it assigned to "arr declared as integer pointer" ?
> When I print the value of "arr" (printf("arr=%p", arr)) in test1.c,
> value printed was 0x100.


> Can you please tell, why the (int *arr) was assigned value 0x100?


It wasn't.

Okay, here's the thing. You declared an int[] containing two values, so
that looks like, in memory:
0x100 0x200
you then told something that, at that location, it would find a pointer.
So the pointer was "0x100".

This behavior depends on a lot of things, including the coincidence that
pointers and ints are the same size, and not all linkers would have done
it, but that's probably what happened.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      02-15-2010
Seebs <(E-Mail Removed)> wrote:
> (E-Mail Removed) <(E-Mail Removed)> wrote:
> > I understand the difference between the types of "arr"
> > in two files.
> > What I wanted to know is what the linker did when it
> > encountered "extern int *arr"?

>
> Whatever it wanted?
>
> > First of all why it didn't give any error ?

>
> Why should it have?


Why shouldn't it have? It's a fair question! If they were in
the same translation unit, the implementation would be required
to issue a diagnostic.

Of course, the answer is that, for historical reasons (which
still exist today,) C implementations tend to operate in
3 stages (well 2 and a bit): pre-processing, compilation and
linking. Traditionally, type information was not passed to
linkers [hence name mangling in most C++ implementations.]

But these days, all sorts of debugging information is
available. So the question of why the standard doesn't
require a diagnostic in this case is a valid one IMO,
even if it should be asked in comp.std.c.

--
Peter
 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      02-15-2010
On 2010-02-15, Peter Nilsson <(E-Mail Removed)> wrote:
> But these days, all sorts of debugging information is
> available. So the question of why the standard doesn't
> require a diagnostic in this case is a valid one IMO,
> even if it should be asked in comp.std.c.


I think it's actually plenty topical here. I doubt that requirement will
make it in "soon", because of the need for support for existing linkers. I'd
personally like to see it, though.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
 
Reply With Quote
 
gwowen
Guest
Posts: n/a
 
      02-16-2010
On Feb 15, 9:39*pm, Peter Nilsson <(E-Mail Removed)> wrote:

> But these days, all sorts of debugging information is
> available. So the question of why the standard doesn't
> require a diagnostic in this case is a valid one IMO,
> even if it should be asked in comp.std.c.


I would guess the answer is "because at the time the standard was
first written, such a clause would have required almost every linker
in the world to be rewritten at a fundamental level". Subsequent to
that the answer is "backwards compatibility".
 
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
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
Cisco 2611 and Cisco 1721 : Why , why , why ????? sam@nospam.org Cisco 10 05-01-2005 08:49 AM
Why, why, why??? =?Utf-8?B?VGltOjouLg==?= ASP .Net 6 01-27-2005 03:35 PM
Why Why Why You HAVE NO IDEA MCSE 31 04-24-2004 06:40 PM



Advertisments