main()
{
char *cp;
int i=300;
cp=&i;
printf("value of byte one in i is%d\n",*cp);
printf("value of byte two in i is%d\n",*(cp+1));
}
Regards,
Satadru
> The following program should output 44 and 1, respectively. But whenever
> I compile this program under Turbo C++ 3.0 for DOS I get the error
> message - " Cannot convert int * into char * ". Please HELP !!!
>
>
> main()
int main(void)
> {
> char *cp;
> int i=300;
> cp=&i;
&i evaluates to type (int *) cp is of type (char *)
if you need to get this assignment, you can try to
convert thru a generic pointer type (void *)
cp = (void *) &i;
or make cp a void pointer and cast at output:
void *cp;
int i=300;
cp = &i;
printf("value of byte one in i is %d\n",*(char *)cp);
printf("value of byte two in i is %d\n",*((char *)cp+1));
> printf("value of byte one in i is%d\n",*cp);
> printf("value of byte two in i is%d\n",*(cp+1));
> }
>
> Regards, Satadru
>
>
>
Z
--
LISP is worth learning for the profound enlightenment experience you
will have when you finally get it; that experience will make you a
better programmer for the rest of your days. Eric S. Raymond
If you are going to convert something that should not be
converted, you have to tell the compiler that you are
willing to accept the risk on your own head. You have to
insert a cast. Something like so.
cp = (char *)&i;
Note that putting one kind of pointer into another is, in
many cases, very troublesome. Probably your sample program
does nothing bad. But in general, it's a less than wonderful
idea. You should be very careful you don't wind up doing
things like running past the memory you own, corrupting
data, mis-interpreting data, etc.
--
grelbr
Free insults!
Sent via Deja.com http://www.deja.com/
Before you buy.
> cp=&i;
Try
cp=(char*)&i;
david
--
FORTRAN was the language of choice for the same reason that three-legged
races are popular.
-- Ken Thompson, "Reflections on Trusting Trust"
int main(void)!!
> {
> char *cp;
> int i=300;
> cp=&i;
>
> printf("value of byte one in i is%d\n",*cp);
> printf("value of byte two in i is%d\n",*(cp+1));
return 0;
> }
>
> Regards,
> Satadru
Your compiler is right, pointer conversions are only safe from
some_type * to void * and from void * back to the same type.
You could trick your compiler and use a void * as temporary pointer
like
char *cp;
int i=300;
void *v = &i;
cp=v;
or use a cast, but (as somebody -anybody ?- here will tell you
immidiately) that is not a good idea
You can use a union for that:
#include <stdio.h>
int main(void)
{
union
{
int i;
unsigned char c[sizeof(int)];
}int_char;
int j;
/* note the unsigned char, it is guaranteed that it cannot be a trap
representation.
Now the char array and the int occupy the same space in memory. */
int_char.i = 300;
/* we store now an integer value in that space,
interpret it as a character array and print the characters. How many
lines we get is implementation - dependent. I used a %x for the
character formatting, because IMO a hex display of the bytes of an
integer makes more sense, but that is up to you. Note also, that
this program does not deal with endianness, so on an x86 machine it
will print the least significant byte first, on other systems it
might print the msb first*/
for(j=0; j < sizeof(int); j++)
{
printf("value of byte %d in i is %x\n", j, int_char.c[j]);
}
return 0;
}
Question to the regulars:
Did I get it right?
Thank you in advance
Robert
--
I don't make my mistakes more than once. I store them carefully and
after some time I take them out again, add some new features and
_reuse_ them.
The biggest problem is the type. The only safe type to use is unsigned char.
The union hack is just as error prone as the pointer hack.
With a union, if you put in an 'x' and pull out a 'y' the result is undefined.
That having been said, it frequently "works."
I think the best 'generic' way to dump the contents of an object is to take an
unsigned char pointer to it and then print out the contents up to
sizeof(object).
Actually, that's the second best way. The best way is to go read about it in
the documentation. (Typically, this gag is used to reverse engineer floating
point formats and things of that nature.)
See also C-FAQ 20.9
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
"The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm
int *cp;
or cast cp in:
cp = (char*)(&i) ;
bye
S M Dev wrote in message <8uq46b$1p4$1...@news.vsnl.net.in>...
>The following program should output 44 and 1, respectively. But whenever I
>compile this program under Turbo C++ 3.0 for DOS I get the error message -
"
>Cannot convert int * into char * ". Please HELP !!!
>
>
>main()
>{
> char *cp;
> int i=300;
> cp=&i;
>
> printf("value of byte one in i is%d\n",*cp);
> printf("value of byte two in i is%d\n",*(cp+1));
>}
>
>Regards,
>Satadru
>
>
>
main()
{
int i=300;
printf("value of byte one in i is%d\n",i & 0xff );
printf("value of byte two in i is%d\n", (i >> 8) & 0xff);
<snip>
> The biggest problem is the type. The only safe type to use is unsigned char.
> The union hack is just as error prone as the pointer hack.
Yes, but I did use unsigned char in my example. Do I misunderstand
you?
>
> With a union, if you put in an 'x' and pull out a 'y' the result is undefined.
> That having been said, it frequently "works."
>
> I think the best 'generic' way to dump the contents of an object is to take an
> unsigned char pointer to it and then print out the contents up to
> sizeof(object).
Is'nt that exactly what I am doing above? AFAIK ther can be no
padding bits at the beginnig of the union, therefor &int_char.c[0]
should point to the first byte of the int and it is a pointer to
unsigned char. Or did I miss something?
>
> Actually, that's the second best way. The best way is to go read about it in
> the documentation. (Typically, this gag is used to reverse engineer floating
> point formats and things of that nature.)
That is the only reason why I would use it, and then it will most
likely be for a use_once_and_forget_it hack :)
Thank you for your comments
Robert
--
Robert Stankowic pcdo...@netway.at
> main()
> {
> int i=300;
> printf("value of byte one in i is%d\n",i & 0xff );
> printf("value of byte two in i is%d\n", (i >> 8) & 0xff);
> }
...which of course only works for 8-bit bytes, not all bytes.
--
/-- Joona Palaste (pal...@cc.helsinki.fi) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #80 D+ ADA N+++ |
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"Show me a good mouser and I'll show you a cat with bad breath."
- Garfield
That is the biggest problem with the FIRST example. With the second program,
the problem below is the biggest error.
> >
> > With a union, if you put in an 'x' and pull out a 'y' the result is
undefined.
> > That having been said, it frequently "works."
> >
> > I think the best 'generic' way to dump the contents of an object is to
take an
> > unsigned char pointer to it and then print out the contents up to
> > sizeof(object).
>
> Is'nt that exactly what I am doing above? AFAIK ther can be no
> padding bits at the beginnig of the union, therefor &int_char.c[0]
> should point to the first byte of the int and it is a pointer to
> unsigned char. Or did I miss something?
You missed something. The C standard says that the behavior is undefined.
Therefore, all the reasons that you can imagine why it might work are
irrelevant.
On the other hand, it usually does work anyway.
> >
> > Actually, that's the second best way. The best way is to go read about it
in
> > the documentation. (Typically, this gag is used to reverse engineer
floating
> > point formats and things of that nature.)
>
> That is the only reason why I would use it, and then it will most
> likely be for a use_once_and_forget_it hack :)
>
> Thank you for your comments
> Robert
--
S M Dev <dev...@vsnl.com> wrote in message
news:8uq46b$1p4$1...@news.vsnl.net.in...
> The following program should output 44 and 1, respectively. But whenever I
> compile this program under Turbo C++ 3.0 for DOS I get the error message -
"
> Cannot convert int * into char * ". Please HELP !!!
>
>
> main()
> {
> char *cp;
> int i=300;
> cp=&i;
>
> printf("value of byte one in i is%d\n",*cp);
> printf("value of byte two in i is%d\n",*(cp+1));
> }
>
> Regards,
> Satadru
>
>
>
In C90, it's implementation-defined.
C90 6.3.2.3, paragraph 5, sentence 1.
That sentence has been mysteriously removed from C99 6.5.2.3, but
the following sentence with the "special guarantee" about
inspecting the common initial sequences of structures in a union
remains. My copy of the Rationale doesn't address the deleted
language, so I'm off to comp.std.c to inquire about it.
--
Morris M. Keesan -- mke...@lucent.com
Lucent Technologies Software Products Group
<snip>
> unsigned char. Or did I miss something?
>
> You missed something. The C standard says that the behavior is undefined.
> Therefore, all the reasons that you can imagine why it might work are
> irrelevant.
Yes, I missed that. I have got just the draft and seem to be unable
to find the paragraph (I guess it is hidden in some refernce to
another paragraph)
I would be grateful if you could tell me where to look.
(I got the draft few days ago and I am in the process of
understandig about one percent of it, but -time will come...- :)
Thank you in advance
>
> On the other hand, it usually does work anyway.
See below...
>
> > >
> > > Actually, that's the second best way. The best way is to go read about it
> in
> > > the documentation. (Typically, this gag is used to reverse engineer
> floating
> > > point formats and things of that nature.)
> >
> > That is the only reason why I would use it, and then it will most
> > likely be for a use_once_and_forget_it hack :)
> >
--
I am not sure that any of this contradicts, but surely if it does not, then it
is a standard defect.
Footnote 37) 6.2.5: "Note that aggregate type does not include union type
because an object with union type can only contain one member at a time."
6.7.2.1 Structure and union specifiers, "Constraints":
"14 The size of a union is sufficient to contain the largest of its members.
The value of at most one of the members can be stored in a union object at any
time. A pointer to a union object, suitably converted, points to each of its
members (or if a member is a bit-field, then to the unit in which it resides),
and vice versa."
J.1 Unspecified behavior:
"1 The following are unspecified:"
[snip]
"— The value of a union member other than the last one stored into (6.2.6.1)."
> "Robert Stankowic" <pcdo...@netway.at> wrote in message
> news:3A1001C6...@netway.at...
> > S M Dev schrieb:
> > >
> > > The following program should output 44 and 1, respectively. But whenever I
> > > compile this program under Turbo C++ 3.0 for DOS I get the error message -
> "
> > > Cannot convert int * into char * ". Please HELP !!!
> > >
> > > main()
> >
> > int main(void)!!
> >
> > > {
> > > char *cp;
> > > int i=300;
> > > cp=&i;
> > >
> > > printf("value of byte one in i is%d\n",*cp);
> > > printf("value of byte two in i is%d\n",*(cp+1));
> >
> > return 0;
> >
> > > }
> > >
> > > Regards,
> > > Satadru
> >
> > Your compiler is right, pointer conversions are only safe from
> > some_type * to void * and from void * back to the same type.
> >
> > You could trick your compiler and use a void * as temporary pointer
> > like
> > char *cp;
> > int i=300;
> > void *v = &i;
> > cp=v;
> > or use a cast, but (as somebody -anybody ?- here will tell you
> > immidiately) that is not a good idea
> >
> > You can use a union for that:
> >
> > #include <stdio.h>
> >
> > int main(void)
> > {
> > union
> > {
> > int i;
> > unsigned char c[sizeof(int)];
> > }int_char;
> > int j;
> > /* note the unsigned char, it is guaranteed that it cannot be a trap
> > representation.
> > Now the char array and the int occupy the same space in memory. */
> >
> > int_char.i = 300;
> > /* we store now an integer value in that space,
> > interpret it as a character array and print the characters. How many
> > lines we get is implementation - dependent. I used a %x for the
> > character formatting, because IMO a hex display of the bytes of an
> > integer makes more sense, but that is up to you. Note also, that
> > this program does not deal with endianness, so on an x86 machine it
> > will print the least significant byte first, on other systems it
> > might print the msb first*/
> >
> > for(j=0; j < sizeof(int); j++)
> > {
> > printf("value of byte %d in i is %x\n", j, int_char.c[j]);
> > }
> > return 0;
> > }
> >
> > Question to the regulars:
> > Did I get it right?
>
>
> The biggest problem is the type. The only safe type to use is unsigned char.
> The union hack is just as error prone as the pointer hack.
>
> With a union, if you put in an 'x' and pull out a 'y' the result is undefined.
> That having been said, it frequently "works."
No, the result is not undefined if you access the data using unsigned
char. 6.5 Paragraph 7 (C99) makes it quite clear that the contents of
a union can always be accessed as an array of unsigned char,
regardless of the lvalue type last used to write to the union.
> I think the best 'generic' way to dump the contents of an object is to take an
> unsigned char pointer to it and then print out the contents up to
> sizeof(object).
This is no different than making a union of the object and an
equivalent sized array of unsigned char.
> Actually, that's the second best way. The best way is to go read about it in
> the documentation. (Typically, this gag is used to reverse engineer floating
> point formats and things of that nature.)
>
> See also C-FAQ 20.9
Jack Klein
--
Home: http://jackklein.home.att.net
[snip]
> That is the biggest problem with the FIRST example. With the second program,
> the problem below is the biggest error.
>
> > >
> > > With a union, if you put in an 'x' and pull out a 'y' the result is
> undefined.
> > > That having been said, it frequently "works."
> > >
> > > I think the best 'generic' way to dump the contents of an object is to
> take an
> > > unsigned char pointer to it and then print out the contents up to
> > > sizeof(object).
> >
> > Is'nt that exactly what I am doing above? AFAIK ther can be no
> > padding bits at the beginnig of the union, therefor &int_char.c[0]
> > should point to the first byte of the int and it is a pointer to
> > unsigned char. Or did I miss something?
>
> You missed something. The C standard says that the behavior is undefined.
> Therefore, all the reasons that you can imagine why it might work are
> irrelevant.
[snip]
Can you cite a standard reference that contradicts 6.5 Paragraph 7
that specifically allows access by a "character type" (and neglects to
mention that unsigned char is the only truly safe character type,
since signed and plain char may have trap representations)?
Jack Klein
--
Home: http://jackklein.home.att.net
> "Jack Klein" <jack...@spamcop.net> wrote in message
> news:L8QQOs8zf28kU4...@4ax.com...
> I am not sure that any of this contradicts, but surely if it does not, then it
> is a standard defect.
>
> Footnote 37) 6.2.5: "Note that aggregate type does not include union type
> because an object with union type can only contain one member at a time."
>
> 6.7.2.1 Structure and union specifiers, "Constraints":
>
> "14 The size of a union is sufficient to contain the largest of its members.
> The value of at most one of the members can be stored in a union object at any
> time. A pointer to a union object, suitably converted, points to each of its
> members (or if a member is a bit-field, then to the unit in which it resides),
> and vice versa."
>
> J.1 Unspecified behavior:
>
> "1 The following are unspecified:"
>
> [snip]
>
> "— The value of a union member other than the last one stored into (6.2.6.1)."
I just posted this over at comp.std.c, because Morris took this
question there. Here it is in full...
==========
On Mon, 13 Nov 2000 20:48:09 GMT, mke...@lucent.com (Morris M.
Keesan) wrote in comp.std.c:
> In C90, accessing a member of a union after a value has been
> stored in a different member results in implementation-defined
> behavior (6.3.2.3 p5). In C99, the sentence which makes this
> implementation-defined has been removed, and N897, the Rationale,
> is silent about this.
>
> Is this behavior now undefined? Can anyone comment on why that
> language was removed from C99?
No, the behavior is defined as (partially) stated by section 6.5,
paragraph 15:
[#7] An object shall have its stored value accessed only by
an lvalue expression that has one of the following types:73)
-- a type compatible with the effective type of the
object,
-- a qualified version of a type compatible with the
effective type of the object,
-- a type that is the signed or unsigned type
corresponding to the effective type of the object,
-- a type that is the signed or unsigned type
corresponding to a qualified version of the effective
type of the object,
-- an aggregate or union type that includes one of the
aforementioned types among its members (including,
recursively, a member of a subaggregate or contained
union), or
-- a character type.
The reason I say partially is that signed char (and plain char, if
signed) may have trap representations and the value of a union might
contain trap representations for these objects, generating undefined
behavior. Since there are no trap representations for unsigned char,
and it is one of the character types, the behavior of accessing any
object as an array of unsigned characters is well-defined.
In fact it not undefined behavior to read uninitialized memory as an
array of unsigned char, provided that you have the right to access the
memory at all. This includes uninitialized local variables or storage
returned by malloc().
Note: I have suggested that the wording above has a defect now that
signed char is allowed to have trap representations. I believe this
and several other similar uses of "character type" or "character
types" can mislead readers into thinking that any memory can be
legally accessed via any character type, whereas this is only true for
unsigned char.
========
The prohibition about punning in general does not override the golden
protection of unsigned char, left alone of the character types (due to
C99 allowing trap representations in signed char) that it can
accessing any object belonging to your program. All of the
prohibitions are based on possible trap representations, and unsigned
char has none.
Thank you all for the precise information :)
Kind regards
do you know not-8-bit bytes ?
bye
luca
Yes. We've had this discussion before, please don't start it
again.
--
Just another C hacker.
Sure. The Analog SHARC 2106x DSP has 32-bit bytes.
--
Richard Heathfield
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
tricky things these compilers! Its telling you you can't convert an
int* into a char*. Because you can't.
> main()
> {
> char *cp;
> int i=300;
> cp=&i;
put an explicit cast in
cp = (char*)&i;
> printf("value of byte one in i is%d\n",*cp);
> printf("value of byte two in i is%d\n",*(cp+1));
> }
But as others have pointed out using an unsigned char* is more correct.
Even with a cast to unsigned char* your program is *still* highly
non-portable (this is why your compiler is screaming). How do you know
an int is twice the size of a char? How do you know you have big endian
or little endian (different machines store the bytes[1] comprising an
int in different orders)?
[1] I misuse the term "byte" here. In the C standard a byte is defined
as equal in size to a char, and a char is defined as at least 8-bits.
Hence a byte may be 8, 9 or even 32 bits. In comp.lang.c "byte" means
"char". If you mean an 8-bit quantity use the term "octet".
--
Dan Pop: "When was the last time you've implemented a real life
application as a strictly conforming program?"
Richard Heathfield: "About 20 minutes ago. It was a new, heavily
optimised pig-launching routine, which gets us a 70% range increase on
previous porcine aeronautic programs."
I don't know if there are BBN C/70s still in use, but when I was
maintaining the C compiler for it, it had 10-bit bytes. We ported lots
of code from Berkeley Unix in those days, and I learned all about the
problems caused by assuming non-portable things about byte size, word
size, relative sizes of int and long, endian-ness, and the presence or
non-presence of zero bits at address zero.