By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,469 Members | 1,259 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,469 IT Pros & Developers. It's quick & easy.

Small C "Puzzle"

P: n/a
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't
really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem). Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?

Thanks,

Rob Gamble
Nov 14 '05 #1
Share this Question
Share on Google+
28 Replies


P: n/a
Robert Gamble <ro**********@hotmail.com> wrote:
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?


Did you check to make sure p != NULL ? There may have been a malloc() failure
for whatever reason.

--
Kristofer Pettijohn
kr*******@cybernetik.net
Nov 14 '05 #2

P: n/a
Robert Gamble <ro**********@hotmail.com> writes:
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't
really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem). Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?


The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value. Since the high-order bits include non-zero values, this loses
information. Casting to int* masks the error, and generates an
invalid pointer value (whose upper half happens to be all-bits-zero).
Dereferencing the pointer value on the next line causes more undefined
behavior, which manifests itself as a seg fault.

It happens to work on IA-32 (more commonly known as x86) because int
and pointer types are both 32 bits. The phrase "happens to work"
means that the undefined behavior manifests itself as the program
doing what you expected it to do. (This is actually worse than what
happens on the IA-64, since it masks the error.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #3

P: n/a
Robert Gamble wrote:

I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have
not had any trouble with any of them except for the first one
which is reproduced below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic,
but I don't really see anything wrong with the code (yes,
stdlib.h is missing, int main(void), and malloc casted, but I
don't think this has anything to do with the point of the
problem). Am I missing something here? I don't have access
to an IA-64 machine, anyone who does have any insight?


Yes it does. Remove the unnecessary cast, which has prevented
compiler warnings, and #include <stdlib.h>, and the problem should
go away.

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '05 #4

P: n/a

"Robert Gamble" <ro**********@hotmail.com> wrote in message
news:pa****************************@hotmail.com...
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't
really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem).
Actually, it *is* the problem. Although 'malloc()'s return value
is cast above, it's already too late. Lacking a proper prototype,
'malloc()' will be assumed to return type 'int'. So the valid
pointer value has already been corrupted by the conversion to
type 'int'. Casting this 'int' back to type 'int*' won't bring
back the original pointer value.(*)
Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?

Thanks,


(*) On some platforms/implementations (e.g. Windows), such conversions
between 'int' and a pointer type are indeed well defined, but not by
the language.

I'm not familiar with the 'IA' machines, but apparently the puzzle
is referring to the fact that trying to convert a pointer to an
int and back to a pointer will *not* work correctly on those
platforms.

-Mike
Nov 14 '05 #5

P: n/a

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
Robert Gamble <ro**********@hotmail.com> writes:
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem). Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?


The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value. Since the high-order bits include non-zero values, this loses
information. Casting to int* masks the error, and generates an
invalid pointer value (whose upper half happens to be all-bits-zero).
Dereferencing the pointer value on the next line causes more undefined
behavior, which manifests itself as a seg fault.

It happens to work on IA-32 (more commonly known as x86)


Ah, so I guess I *do* know what an 'IA' machine is. :-)
(In my other post I said I did not.)

-Mike
Nov 14 '05 #6

P: n/a
On Fri, 27 Aug 2004 23:38:11 +0000, Keith Thompson wrote:
Robert Gamble <ro**********@hotmail.com> writes:
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't
really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem). Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?


The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value. Since the high-order bits include non-zero values, this loses
information. Casting to int* masks the error, and generates an
invalid pointer value (whose upper half happens to be all-bits-zero).
Dereferencing the pointer value on the next line causes more undefined
behavior, which manifests itself as a seg fault.

It happens to work on IA-32 (more commonly known as x86) because int
and pointer types are both 32 bits. The phrase "happens to work"
means that the undefined behavior manifests itself as the program
doing what you expected it to do. (This is actually worse than what
happens on the IA-64, since it masks the error.)


I really did not consider this an option due to the fact that all the
other examples on the site cast malloc and declare main the same way. I
did just check though and all of the other examples do include proper
header files. I was overlooking the obvious thinking that there was a
deeper issue at work.

Thanks for the detailed explanation. Another reason I dismissed this as
my original answer was that I was thinking that int was 64 bits on IA-64
which did not seem any different from what would be happening on a 32-bit
machine. I'd forgotten this was not the case with most enviornments until
I read your post (I don't program on 64-bit machines yet ;)

I didn't want to beleive this was the answer because it didn't seem as
clear-cut as the other puzzles, kind of obvious and anti-climactic, but
you have talked me into it ;)

Thanks,

Rob Gamble
Nov 14 '05 #7

P: n/a
On Fri, 27 Aug 2004 23:38:11 GMT, Keith Thompson <ks***@mib.org> wrote
in comp.lang.c:
Robert Gamble <ro**********@hotmail.com> writes:
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't
really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem). Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?


The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value.


Doesn't make any difference what size int or pointers are. The code
has undefined behavior because it calls ANY function with a return
type other than int without a prototype in scope. Period. Size of
anything irrelevant.

--
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 14 '05 #8

P: n/a
> > The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant ...

The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value. Since the high-order bits include non-zero values, this loses
information. Casting to int* masks the error, and generates an
invalid pointer value (whose upper half happens to be all-bits-zero).
Dereferencing the pointer value on the next line causes more undefined
behavior, which manifests itself as a seg fault.

It happens to work on IA-32 (more commonly known as x86) because int
and pointer types are both 32 bits. The phrase "happens to work"
means that the undefined behavior manifests itself as the program
doing what you expected it to do. (This is actually worse than what
happens on the IA-64, since it masks the error.)


I am little confused about the explanation.
I think size of "int" is size of processor register length.
And malloc retuns 64 bit address and pointer is also 64 bit (whether
int * or char *) , then where actually the size giving problem.

And can i know how the code below behaves on both platforms,

int main()
{
char* p;
p = (char*)malloc(sizeof(char));
*p = 10;
return 0;
}
Nov 14 '05 #9

P: n/a

"Raju" <g_**************@yahoo.co.in> wrote

I am little confused about the explanation.
I think size of "int" is size of processor register length.
And malloc retuns 64 bit address and pointer is also 64 bit (whether
int * or char *) , then where actually the size giving problem.

And can i know how the code below behaves on both platforms,

int main()
{
char* p;
p = (char*)malloc(sizeof(char));
*p = 10;
return 0;
}


int *s and char *s are almost always the same size. ints are typically the
size of data registers, which are commonly but not always the size of
address registers (and on many architectures a register has a dual use). So
in early versions of C it was in fact accepted to assign a pointer to an
int, which is why we have the current problem of prototypes being essential
to make things work correctly.

If an int and a pointer are both 64 bits, then the undefined behaviour of
calling malloc() without a protoype in scope should normally be the
behaviour the programmer expects. In this case it appears that int was 32
bits and pointers 64 bits, so the ujndefined beahviour instead manifested
itself as a crash.
However there could be problems even if ints and pointers are the same
width, for instance the act of loading an address into a data register could
trigger a crash. With undefined behaviour, you just don't know.
Nov 14 '05 #10

P: n/a
Jack Klein <ja*******@spamcop.net> writes:
On Fri, 27 Aug 2004 23:38:11 GMT, Keith Thompson <ks***@mib.org> wrote
in comp.lang.c:

[...]
In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value.


Doesn't make any difference what size int or pointers are. The code
has undefined behavior because it calls ANY function with a return
type other than int without a prototype in scope. Period. Size of
anything irrelevant.


You're right, of course. (I did mention later that it's also
undefined behavior on the IA-32, where int and pointer types are the
same size, but in the quoted paragraph I inadvertently implied a
cause-and-effect relationship that doesn't exist.)

The difference in size does make a difference, in this case, in the
visible result of the undefined behavior.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #11

P: n/a
g_**************@yahoo.co.in (Raju) writes:
[...]
I am little confused about the explanation.
I think size of "int" is size of processor register length.
And malloc retuns 64 bit address and pointer is also 64 bit (whether
int * or char *) , then where actually the size giving problem.
The size of "int" is whatever the compiler implementer decides it
should be. On the IA-64 (also known as Itanium), int is 32 bits, and
pointers are 64 bits. More precisely, these are the sizes chosen by
the compilers I'm familiar with on IA-64 systems (gcc and Intel's
compiler under Linux). Note that there's a strong motivation for
different compilers on the same system to be compatible with each
other.

Since the IA-64 is a 64-bit system, it's natural to assume that int
should be 64 bits, but that would actually cause some problems.
Currently, the types of the predefined integer types are:

char 8 bits
short 16 bits
int 32 bits
long 64 bits
long long 64 bits

If int were 64 bits, short would be either 16 or 32 bits, leaving a
gap in the type system. (C99 allows extended integer types, with
appropriate typedefs in <stdint.h>, but portable code can't yet depend
on this.)
And can i know how the code below behaves on both platforms,

int main()
{
char* p;
p = (char*)malloc(sizeof(char));
*p = 10;
return 0;
}


With the understanding that it's undefined behavior regardless
of the underlying system:

On IA-32: no ouput.
On IA-64: Segmentation fault.

Here's another program that shows more clearly what's going on:

#ifdef INCLUDE_STDLIB
#include <stdlib.h>
#endif
#include <stdio.h>
int main()
{
char* p;
p = (char*)malloc(sizeof(char));
printf("p = %p\n", p);
fflush(stdout);
*p = 10;
return 0;
}

On IA-32, this produces nearly the same output whether INCLUDE_STDLIB
is defined or not:

p = 0x8648008

(The specific address changes for some irrelevant reason.)

On IA-64, if INCLUDE_STDLIB is not defined, the output is:

p = 0xc80
Segmentation fault

If INCLUDE_STDLIB is defined, the output is:

p = 0x6000000000000c80

Of course none if this arises if you just write the code properly in
the first place: use a "#include <stdlib.h>" directive, and don't cast
the result of malloc().

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #12

P: n/a
>If an int and a pointer are both 64 bits, then the undefined behaviour of
calling malloc() without a protoype in scope should normally be the
behaviour the programmer expects. In this case it appears that int was 32
bits and pointers 64 bits, so the ujndefined beahviour instead manifested
itself as a crash.
The unstated assumption here, which is false, is that the linkage
conventions for two types of the same size are the same. This is
often not true. Even on an Intel [3456]86 platform, integers and
floating point numbers are often (but not always) returned in a
different place.

For example, on a 680X0 processor it is quite possible (and logical)
to return pointers in the a0 register and integers in the d0 register
and floating point numbers in the top of the stack of the floating-point
unit. If the return type of the function is not known, the calling
code may retrieve the return value *FROM THE WRONG PLACE*. No amount
of casting the result will fix that.
However there could be problems even if ints and pointers are the same
width, for instance
the act of loading an address into a data register could
trigger a crash. This I would think would be rather unusual. However, loading an
address register with uninitialized or otherwise arbitrary bit
patterns is much more likely to cause a crash.
With undefined behaviour, you just don't know.


If you load data from the WRONG register, copying it to the "right"
register won't help, and the issue that loading crap into a register
might cause problems is a completely separate problem.

Gordon L. Burditt
Nov 14 '05 #13

P: n/a
Mike Wahler wrote:
I'm not familiar with the 'IA' machines, but apparently the
puzzle is referring to the fact that trying to convert a pointer
to an int and back to a pointer will *not* work correctly on
those platforms.


AFAIK, IA stands for Intel Architecture.

Thus IA-32 is Intel's 32-bit ISA, i.e. x86, and IA-64 is Intel's
64-bit ISA, i.e. the Itanium Processor Family ISA.

--
Regards, Nudge

Nov 14 '05 #14

P: n/a

"Raju" <g_**************@yahoo.co.in> wrote in message
news:3a**************************@posting.google.c om...
The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant ... The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value. Since the high-order bits include non-zero values, this loses
information. Casting to int* masks the error, and generates an
invalid pointer value (whose upper half happens to be all-bits-zero).
Dereferencing the pointer value on the next line causes more undefined
behavior, which manifests itself as a seg fault.

It happens to work on IA-32 (more commonly known as x86) because int
and pointer types are both 32 bits. The phrase "happens to work"
means that the undefined behavior manifests itself as the program
doing what you expected it to do. (This is actually worse than what
happens on the IA-64, since it masks the error.)


I am little confused about the explanation.
I think size of "int" is size of processor register length.
And malloc retuns 64 bit address and pointer is also 64 bit (whether
int * or char *) , then where actually the size giving problem.

And can i know how the code below behaves on both platforms,

int main()
{
char* p;
p = (char*)malloc(sizeof(char));
*p = 10;
return 0;
}


Yup you are right. But you might note that even if a compiler is supporting
64 bit arch. It will in many cases keep int's to be 32 bit's { to keep
backward compatiblity for applications written assuming int to be 32 bits }
That said I think that is just a guess. For I really haven't used any 64 bit
compilers. Can anyone share the current trends in this 64 bit industry. gcc,
MS cl etc.

--
Imanpreet Singh Arora
If I would have only known, I would have been a locksmith.
-- Albert Einstein

Nov 14 '05 #15

P: n/a

"Jack Klein" <ja*******@spamcop.net> wrote in message
news:fa********************************@4ax.com...
On Fri, 27 Aug 2004 23:38:11 GMT, Keith Thompson <ks***@mib.org> wrote
in comp.lang.c:
Robert Gamble <ro**********@hotmail.com> writes:
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had any trouble with any of them except for the first one which is reproduced below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do with the point of the problem). Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?


The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value.


Doesn't make any difference what size int or pointers are. The code
has undefined behavior because it calls ANY function with a return
type other than int without a prototype in scope. Period. Size of
anything irrelevant.

Yes, but the question is why it would work on IA-32 not IA-64. And IA-32 has
same size and representation specification for pointers and int's alike.
--
Imanpreet Singh Arora
If I would have only known, I would have been a locksmith.
-- Albert Einstein

Nov 14 '05 #16

P: n/a
Minti:

You e-mailed me a question in response to something I posted on this
thread. Please post any questions to the newsgroup. If you must send
me e-mail, don't use a spam-blocked return address. (If kissmyass.com
is meant to be a spam trap, you should pick a different one; it
happens to be a real domain, and you could be subjecting its owner to
spam that was meant for you.)

In answer to your question, it is never necessary to cast the result
of malloc() in C; it only masks errors. This is from the latest
version of the C FAQ (the web version hasn't yet been updated):

7.7: Why does some code carefully cast the values returned by malloc
to the pointer type being allocated?

A: Before ANSI/ISO Standard C introduced the void * generic pointer
type, these casts were typically required to silence warnings
(and perhaps induce conversions) when assigning between
incompatible pointer types.

Under ANSI/ISO Standard C, these casts are no longer necessary,
and in fact modern practice discourages them, since they can
camouflage important warnings which would otherwise be generated
if malloc() happened not to be declared correctly; see question
7.6 above. (However, the casts are typically seen in C code
which for one reason or another is intended to be compatible
with C++, where explicit casts from void * are required.)

References: H&S Sec. 16.1 pp. 386-7.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #17

P: n/a

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
g_**************@yahoo.co.in (Raju) writes:
[...]
I am little confused about the explanation.
I think size of "int" is size of processor register length.
And malloc retuns 64 bit address and pointer is also 64 bit (whether
int * or char *) , then where actually the size giving problem.


The size of "int" is whatever the compiler implementer decides it
should be. On the IA-64 (also known as Itanium), int is 32 bits, and
pointers are 64 bits. More precisely, these are the sizes chosen by
the compilers I'm familiar with on IA-64 systems (gcc and Intel's
compiler under Linux). Note that there's a strong motivation for
different compilers on the same system to be compatible with each
other.

Since the IA-64 is a 64-bit system, it's natural to assume that int
should be 64 bits, but that would actually cause some problems.
Currently, the types of the predefined integer types are:

char 8 bits
short 16 bits
int 32 bits
long 64 bits
long long 64 bits

If int were 64 bits, short would be either 16 or 32 bits, leaving a
gap in the type system. (C99 allows extended integer types, with
appropriate typedefs in <stdint.h>, but portable code can't yet depend
on this.)
And can i know how the code below behaves on both platforms,

int main()
{
char* p;
p = (char*)malloc(sizeof(char));
*p = 10;
return 0;
}


With the understanding that it's undefined behavior regardless
of the underlying system:

On IA-32: no ouput.
On IA-64: Segmentation fault.

Here's another program that shows more clearly what's going on:

#ifdef INCLUDE_STDLIB
#include <stdlib.h>
#endif
#include <stdio.h>
int main()
{
char* p;
p = (char*)malloc(sizeof(char));
printf("p = %p\n", p);
fflush(stdout);
*p = 10;
return 0;
}

On IA-32, this produces nearly the same output whether INCLUDE_STDLIB
is defined or not:

p = 0x8648008

(The specific address changes for some irrelevant reason.)

On IA-64, if INCLUDE_STDLIB is not defined, the output is:

p = 0xc80
Segmentation fault

If INCLUDE_STDLIB is defined, the output is:

p = 0x6000000000000c80

Of course none if this arises if you just write the code properly in
the first place: use a "#include <stdlib.h>" directive, and don't cast
the result of malloc().

Why not cast? Are you saying this in context with the IA-64 thingy or just
as a general thingy? I probably have never understood the need to cast or
not to cast. I seem to consider it to be more of a matter of taste rather
than anything else now. I have seen lot of debate, Bjarne says use cast,
everyone here says no.

--
Imanpreet Singh Arora
If I would have only known, I would have been a locksmith.
-- Albert Einstein

Nov 14 '05 #18

P: n/a

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
Minti:

You e-mailed me a question in response to something I posted on this
thread. Please post any questions to the newsgroup. If you must send
me e-mail, don't use a spam-blocked return address. (If kissmyass.com
is meant to be a spam trap, you should pick a different one; it
happens to be a real domain, and you could be subjecting its owner to
spam that was meant for you.)


Thanks, my mail program is configured to send both mail and post it to the
newsgroup, however as a I later checked up after disconnecting that it had
failed to upload the message. Ooops.
Thanks. Again.

--
Imanpreet Singh Arora
Isingh A Acm Dot Org
Nov 14 '05 #19

P: n/a
Minti wrote:
Why not cast? Are you saying this in context with the IA-64
thingy or just as a general thingy? I probably have never
understood the need to cast or not to cast. I seem to consider it
to be more of a matter of taste rather than anything else now. I
have seen lot of debate, Bjarne says use cast, everyone here says
no.


You need to tell your friend Bjarne to use a different language.
C++ perhaps?

^_^

Nov 14 '05 #20

P: n/a
Minti wrote:
"Keith Thompson" <ks***@mib.org> wrote in message

.... snip ...

Of course none if this arises if you just write the code properly
in the first place: use a "#include <stdlib.h>" directive, and
don't cast the result of malloc().


Why not cast? Are you saying this in context with the IA-64 thingy
or just as a general thingy? I probably have never understood the
need to cast or not to cast. I seem to consider it to be more of a
matter of taste rather than anything else now. I have seen lot of
debate, Bjarne says use cast, everyone here says no.


He is talking about C++. Here we talk about C. They are not the
same language.

--
"Churchill and Bush can both be considered wartime leaders, just
as Secretariat and Mr Ed were both horses." - James Rhodes.
"We have always known that heedless self-interest was bad
morals. We now know that it is bad economics" - FDR

Nov 14 '05 #21

P: n/a

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
Minti:
<snip>

In answer to your question, it is never necessary to cast the result of malloc() in C; it only masks errors. This is from the latest
version of the C FAQ (the web version hasn't yet been updated):

7.7: Why does some code carefully cast the values returned by malloc
to the pointer type being allocated?

A: Before ANSI/ISO Standard C introduced the void * generic pointer
type, these casts were typically required to silence warnings
(and perhaps induce conversions) when assigning between
incompatible pointer types.

Under ANSI/ISO Standard C, these casts are no longer necessary,
and in fact modern practice discourages them, since they can
camouflage important warnings which would otherwise be generated
if malloc() happened not to be declared correctly; see question
7.6 above. (However, the casts are typically seen in C code
which for one reason or another is intended to be compatible
with C++, where explicit casts from void * are required.)

References: H&S Sec. 16.1 pp. 386-7.

Well the web version at http://www.eskimo.com/~scs/C-faq/q7.7.html is just
an abridged version of this answer. But pardon me for being an ass-hole. But
after reading 7.6 from http://www.eskimo.com/~scs/C-faq/q7.6.html, I just
think that as long as <stdlib.h> is included there is NO need to have cast.
And if I am doing it I am neither hurting myself nor benefiting myself.
Except for the fact that if it is to be used with a C++ compiler { possibly
later } I won't have to "recast" my code.
--
Imanpreet Singh Arora
isingh AT acm DOT org
If I would have only known, I would have been a locksmith.
-- Albert Einstein

Nov 14 '05 #22

P: n/a
"Minti" <mi************@yahoo.com> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
Minti:

You e-mailed me a question in response to something I posted on this
thread. Please post any questions to the newsgroup. If you must send
me e-mail, don't use a spam-blocked return address. (If kissmyass.com
is meant to be a spam trap, you should pick a different one; it
happens to be a real domain, and you could be subjecting its owner to
spam that was meant for you.)


Thanks, my mail program is configured to send both mail and post it to the
newsgroup, however as a I later checked up after disconnecting that it had
failed to upload the message. Ooops.


Please reconfigure your mail program so it *doesn't* send your both
messages both by e-mail and to the newsgroup.

More precisely, it's your mail program, so you can configure it any
way you like, but please don't send *me* e-mail messages that
duplicate what you post to Usenet. I'm sure that most other people
here feel the same way (I've seen plenty of complaints about the
practice). My complaint wasn't that your message didn't show up on
the newsgroup, it was that it did show up in my mailbox.

And please seriously consider what I wrote above about kissmyass.com.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #23

P: n/a
"Minti" <mi************@yahoo.com> writes:
[...]
Well the web version at http://www.eskimo.com/~scs/C-faq/q7.7.html is just
an abridged version of this answer.
Actually, the version I quoted is a newer (and better) version than
the one on the web.
But after reading 7.6 from
http://www.eskimo.com/~scs/C-faq/q7.6.html, I just think that as
long as <stdlib.h> is included there is NO need to have cast.
Absolutely.
And
if I am doing it I am neither hurting myself nor benefiting myself.
You're potentially masking the error of leaving out the "#include
<stdlib.h>". At best, you're overriding the compiler by forcing it to
do what it would have done anyway.
Except for the fact that if it is to be used with a C++ compiler {
possibly later } I won't have to "recast" my code.


Why would you want to compile C code with a C++ compiler? They're two
different languages. (P.J. Plauger has explained is valid reasons for
doing this; very few other people should need to worry about it.)

If you want to write C++, write C++ (which means using new/delete
rather than malloc()/free().)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #24

P: n/a
Keith Thompson <ks***@mib.org> writes:
[...]
Why would you want to compile C code with a C++ compiler? They're two
different languages. (P.J. Plauger has explained is valid reasons for
doing this; very few other people should need to worry about it.)


Sorry, that was a typo; I meant to say that P.J. Plauger has explained
*his* valid reasons for compiling C code with a C++ compiler.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #25

P: n/a
In article <41**********************@news.free.fr>, ho******@kma.eu.org says...
Mike Wahler wrote:
I'm not familiar with the 'IA' machines, but apparently the
puzzle is referring to the fact that trying to convert a pointer
to an int and back to a pointer will *not* work correctly on
those platforms.


AFAIK, IA stands for Intel Architecture.

Thus IA-32 is Intel's 32-bit ISA, i.e. x86, and IA-64 is Intel's
64-bit ISA, i.e. the Itanium Processor Family ISA.


And just to make it more confusing, Intel has started offering 64-bit
CPUs which effectively are clones of the AMD Opteron (apart from a
single instruction IIRC) which are collectively referred to as x86-64.
They (Intel) keep changing the marketing name, I think the latest
incantation is "EM64t".

Itanium != Opteron by any stretch of the imagination, although they
are both 64-bit processors.

--
Randy Howard
To reply, remove FOOBAR.
Nov 14 '05 #26

P: n/a
You must havn't included the "malloc.h". At 64bit , the return value of a
function is defaulted to "int" if the declaration is not present.

Thanks!
Wei

"Robert Gamble" <ro**********@hotmail.com> wrote in message
news:pa****************************@hotmail.com...
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and have not had
any trouble with any of them except for the first one which is reproduced
below:

The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic, but I don't
really see anything wrong with the code (yes, stdlib.h is missing, int
main(void), and malloc casted, but I don't think this has anything to do
with the point of the problem). Am I missing something here? I don't
have access to an IA-64 machine, anyone who does have any insight?

Thanks,

Rob Gamble

Nov 14 '05 #27

P: n/a
Wei Li wrote:
"Robert Gamble" <ro**********@hotmail.com> wrote in message
I was taking a look at some of the C puzzles at:
http://purana.csa.iisc.ernet.in/~gkumar/cquestions.html and
have not had any trouble with any of them except for the first
one which is reproduced below:

The following C program segfaults of IA-64, but works fine on
IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?

Now I know that architecture dependant behavior is off-topic,
but I don't really see anything wrong with the code (yes,
stdlib.h is missing, int main(void), and malloc casted, but I
don't think this has anything to do with the point of the
problem). Am I missing something here? I don't have access to
an IA-64 machine, anyone who does have any insight?


You must havn't included the "malloc.h". At 64bit , the return
value of a function is defaulted to "int" if the declaration is
not present.


malloc.h is not a standard include file. stdlib.h is
appropriate. As others have pointed out, the problem is the lack
of the include together with the cast, which suppresses the
compiler warning.

--
"Churchill and Bush can both be considered wartime leaders, just
as Secretariat and Mr Ed were both horses." - James Rhodes.
"We have always known that heedless self-interest was bad
morals. We now know that it is bad economics" - FDR
Nov 14 '05 #28

P: n/a
On Tue, 31 Aug 2004 15:29:31 -0700
"Wei Li" <li*************@yahoo.com> wrote:
You must havn't included the "malloc.h". At 64bit , the return value
of a function is defaulted to "int" if the declaration is not present.


<snip>

Please don't top-post. Replies belong under the text you are replying to
and what is not needed for context should be snipped.

malloc.h is a non-standard header. The header that provides a prototype
for malloc is stdlib.h
--
Flash Gordon
Sometimes I think shooting would be far too good for some people.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #29

This discussion thread is closed

Replies have been disabled for this discussion.