int pointing to char

G

Gautam

this piece of code assigns an int pointer(evident) to a char,
and when i try to access the ascii value of the char through the
integer pointer(p) ,

what i get is a junk value or not i don't know !
'cause it shows consistent values for diff. chars , for eg.


c = 'a' ans=>-9119

c = 'b' ans=>-9118

c = 'c' ans=>-9117

... and so on


#include <stdio.h>

void main()
{
char c = 'a';
int * p;

p = &c; /*suspicious pointer conversion WARNING !*/
clrscr();
pf("\n%d", *p);
getch();
}



. . . . whats happening ?

Gautam
 
J

James Hu

this piece of code assigns an int pointer(evident) to a char,
and when i try to access the ascii value of the char through the
integer pointer(p) ,

what i get is a junk value or not i don't know !
'cause it shows consistent values for diff. chars , for eg.


c = 'a' ans=>-9119

c = 'b' ans=>-9118

c = 'c' ans=>-9117

... and so on


#include <stdio.h>

void main()
{
char c = 'a';
int * p;

p = &c; /*suspicious pointer conversion WARNING !*/
clrscr();
pf("\n%d", *p);
getch();
}

Your compiler seems to be doing its job, according to your comment,
and is warning you that you are doing something wrong. This means
you should fix it. Change the type of c so that p can point to it.

Since you appear to be learning C, you should try to stick to the
standard language features. pf(), clrscr() and getch() are not part of
the standard C language. In standard C in a hosted environment, main
returns an int.

#include <stdio.h>

int main(void)
{
int c = 'a';
int * p;

p = &c;
printf("%d\n", *p);
return 0;
}
. . . . whats happening ?

You are lying to the compiler about what p is pointing to. Assuming
that pf() in your program is not #defined to be an empty statement,
your program results in undefined behavior, so anything could happen.

-- James
 
D

Dan Pop

In said:
this piece of code assigns an int pointer(evident) to a char,

Nope, it doesn't.
and when i try to access the ascii value of the char through the
integer pointer(p) ,

An operation devoid of any sense. If you want to access the value of the
char through a pointer, you NEED a pointer to char. No other pointer
type is suitable for the job.
#include <stdio.h>

void main()

So, you didn't bother to read the FAQ *before* posting...
{
char c = 'a';
int * p;

p = &c; /*suspicious pointer conversion WARNING !*/

It's actually a fatal programing error, as far as your program is
concerned. NEVER ignore a compiler warning *before* understanding its
meaning.
clrscr();

What's this nonsense?
pf("\n%d", *p);

What's this nonsense?

What's this nonsense?
}

. . . . whats happening ?

You're misdefining main(), incorrectly initialising a pointer,
incorrectly using the same pointer and calling a lot functions that
neither your program nor the standard C library defines. What would
you expect to happen?!?

Compare your piece of garbage with the following program that correctly
uses a pointer to figure out the value of 'a':

#include <stdio.h>

int main()
{
char c = 'a';
char *p = &c;

printf("%d\n", *p);
return 0;
}

An equally correct way is by defining c as int and p as pointer to int.

There are cases when you want a pointer to unsigned char to point to the
address of an object of another type, but all the other object pointer
types should point to the address of an object of the corresponding type.

Only experts have a licence to ignore this rule, because they know what
they're doing.

Dan
 
C

CBFalconer

Gautam said:
this piece of code assigns an int pointer(evident) to a char,
and when i try to access the ascii value of the char through the
integer pointer(p) ,

what i get is a junk value or not i don't know !
'cause it shows consistent values for diff. chars , for eg.

c = 'a' ans=>-9119
c = 'b' ans=>-9118
c = 'c' ans=>-9117
... and so on

#include <stdio.h>

void main()

Undefined behaviour. Use "int main(void)"
{
char c = 'a';
int * p;

p = &c; /*suspicious pointer conversion WARNING !*/

Well? why didn't you do something about it?
clrscr();

no such function.
pf("\n%d", *p);

no such function.

no such function.
}

. . . . whats happening ?

Compare to:

#include <stdio.h>
int main(void)
{
int c = 'a';
int *p;

p = &c;
printf("%d\n", *p);
return 0;
}

and compare the resultant values with those you got. That may
give you some clue as to what is going on in your machine even
with all the undefined behavior.
 
G

gregg

James said:
You are lying to the compiler about what p is pointing to. Assuming
that pf() in your program is not #defined to be an empty statement,
your program results in undefined behavior, so anything could happen.

Is it an undefined behaviour, or result ?

I mean, since c is declared to be a char (ie 1 byte, according to ISO-C)
and p is an int* (pointer to 2, or 4 bytes), the program reaches the
memory and reads 2 (or 4) bytes instead of just one.
This is defined as far as behaviour is concerned.
The result itself being undefined (we don't know what's in second, third
and fourth byte).

I'm a bit confused with terminology here... :-(
 
C

Clark Cox

gregg said:
Is it an undefined behaviour, or result ?

It's undefined behavior. What does pf do? We don't know, it's not
defined anywhere. The only way that that line could be well defined is
if you had a line similar to the following in your code:

#define pf(x,y)

Which would replace your line with a blank one.
I mean, since c is declared to be a char (ie 1 byte, according to ISO-C)
and p is an int* (pointer to 2, or 4 bytes),

There's nothing stopping int from being 1 byte, 3 bytes or 20 bytes.
the program reaches the
memory and reads 2 (or 4) bytes instead of just one.
This is defined as far as behaviour is concerned.

No, it isn't. If sizeof(char) != sizeof(int), you're attempting to
read from memory that you haven't allocated. That's undefined behavior.
Your program might crash, it might give you a random value, or anything
else may happen.
The result itself being undefined (we don't know what's in second, third
and fourth byte).

The result *is* undefined ... because the *behavior* is undefined to
begin with.
 
M

Martin Ambuhl

Gautam said:
this piece of code assigns an int pointer(evident) to a char,
and when i try to access the ascii value of the char through the
integer pointer(p) ,
what i get is a junk value or not i don't know !
'cause it shows consistent values for diff. chars , for eg.

Every once in a while, someone decides to post the worst possible excuse
for a C program. Yours is in that group, though you forgot to leave off
the #include statement.

Here's your "code":
#include <stdio.h>

void main()
{
char c = 'a';
int * p;

p = &c; /*suspicious pointer conversion WARNING !*/
clrscr();
pf("\n%d", *p);
getch();
}

And here's something closer to C:

#include <stdio.h>

int main()
{
char c = 'a';
char *p = &c;
printf("%d\n", (int) *p);
return 0;
}
 
G

gregg

Clark said:
No, it isn't. If sizeof(char) != sizeof(int), you're attempting to
read from memory that you haven't allocated. That's undefined behavior.
Your program might crash, it might give you a random value, or anything
else may happen.

Right, i got it now !
thanks

g.
 
O

Old Wolf

this piece of code assigns an int pointer(evident) to a char,
You are lying to the compiler about what p is pointing to. Assuming
that pf() in your program is not #defined to be an empty statement,
your program results in undefined behavior, so anything could happen.

Actually, undefined behaviour is introduced by "void main()",
and also by the line "p = &c;" (for example, it could produce
a hardware exception on a device which requires int pointers
to be correctly aligned). It is UB to point a pointer to an
object of an incompatible type.
 
J

James Hu

Actually, undefined behaviour is introduced by "void main()",

I generally ignore this, since it may be valid in a freestanding
environment.
and also by the line "p = &c;" (for example, it could produce
a hardware exception on a device which requires int pointers
to be correctly aligned).

What would such hardware do when presented with:

char c = 'a';
void *q = &c;
int *p = q;

?
It is UB to point a pointer to an object of an incompatible type.

I don't believe a constraint violation results in undefined behavior,
but IANACLL (xref: 6.5.16.1p1 and 4p1).

However, even though p holds a valid character pointer value, it holds
an invalid integer pointer value, and therefore indirection yields UB
when applied on p (xref: 6.5.3.2p4).

-- James
 
P

pete

James said:
I generally ignore this, since it may be valid in a freestanding
environment.


What would such hardware do when presented with:

char c = 'a';
void *q = &c;
int *p = q;

?


I don't believe a constraint violation results in undefined behavior,
but IANACLL (xref: 6.5.16.1p1 and 4p1).

If a constraint is violated,
then you don't know what the code means,
and that's undefined behavior.

N869
3. Terms and definitions
3.6
[#1] constraints
restrictions, both syntactic and semantic, by which the
exposition of language elements is to be interpreted
 
D

Dan Pop

In said:
Actually, undefined behaviour is introduced by "void main()",
and also by the line "p = &c;"

Nope, this is a constraint violation and requires a diagnostic. Mere
undefined behaviour doesn't.
(for example, it could produce
a hardware exception on a device which requires int pointers
to be correctly aligned). It is UB to point a pointer to an
object of an incompatible type.

Only in certain cases, when the incompatible type has looser alignment
requirements. Character pointers (of all three types) can be pointed to
any object. Pointers to unsigned char can even be safely dereferenced
after that. A pointer to int can be safely made to point to a struct
whose first member has type int. It can be even dereferenced, if the
struct member has already been initialised.

Dan
 
D

Dan Pop

In said:
If a constraint is violated,
then you don't know what the code means,
and that's undefined behavior.

This is correct. The important point is that the constraint violation
*requires* a diagnostic, while a mere invocation of undefined behaviour
doesn't.

After the diagnostic is produced, there is no difference between the
two, because the standard doesn't specify the semantics of any code
that contains syntax errors or constraint violations.

Dan
 
J

James Hu

This is correct. The important point is that the constraint violation
*requires* a diagnostic, while a mere invocation of undefined behaviour
doesn't.

After the diagnostic is produced, there is no difference between the
two, because the standard doesn't specify the semantics of any code
that contains syntax errors or constraint violations.

Like I said, IANACLL, but my understanding was that the behavior of a
constraint violation is unspecified behavior, not undefined behavior.

A program can still be correct if it contains unspecified behavior
(xref: 4p3).

-- James
 
D

Dan Pop

In said:
Like I said, IANACLL, but my understanding was that the behavior of a
constraint violation is unspecified behavior, not undefined behavior.

3.4.4
1 unspecified behavior
behavior where this International Standard provides two or more
possibilities and imposes no further requirements on which is
chosen in any instance

When a constraint is violated, the standard doesn't provide *any*
possibilities the implementation can choose from, either explicitly or
implicitly.

For example:

6.5.2.1 Array subscripting

Constraints

1 One of the expressions shall have type ``pointer to object type'',
the other expression shall have integer type, and the result
has type ``type''.

What are the allowed possibilities for the type of a when both a and b
have type double?
A program can still be correct if it contains unspecified behavior
(xref: 4p3).

But a program CANNOT be correct if it violates a constraint. That's why
they're called "constraints" in the first place.

A correct C program (from the standard's POV) is a program that
doesn't require any diagnostic and doesn't invoke undefined behaviour.

Dan
 
J

James Hu

I should qualify that with "c.v. doesn't necessarily result in u'd.b.".
Like I said, IANACLL, but my understanding was that the behavior of a
constraint violation is unspecified behavior, not undefined behavior.

Since I have only be looking at the assignment operator, this statement
should be restricted to the assignment in question:

char c = 'a';
int *p = &a;

-- James
 
D

Dan Pop

In said:
I should qualify that with "c.v. doesn't necessarily result in u'd.b.".


Since I have only be looking at the assignment operator, this statement
should be restricted to the assignment in question:

char c = 'a';
int *p = &c;

The C standard doesn't classify constraint violations in several
categories. ALL of them have the same effect: a diagnostic is required
after which there are no more requirements from the implementation.
An implementation aborting the translation process after issuing a
required diagnostic would be perfectly conforming.

If all C compilers failed to translate code *requiring* a diagnostic,
C would be a better known language. Far too many incompetents discard
ALL the warnings by default, without trying to understand if they signal
a real problem or not. If the program appears to work as expected, it
*must* be correct.

Dan
 
O

Old Wolf

char c = 'a';
int * p;

p = &c; /*suspicious pointer conversion WARNING !*/ [snips]
. . . . whats happening ?

You are lying to the compiler about what p is pointing to. Assuming
that pf() in your program is not #defined to be an empty statement,
your program results in undefined behavior, so anything could happen.

Actually, undefined behaviour is introduced by "void main()",

I generally ignore this, since it may be valid in a freestanding
environment.

I generally ignore freestanding environments, as you could raise
the objection "it may be valid in a f.e." to just about anything
posted on c.l.c.
FWIW, void main() may be valid in a hosted environment too.
What would such hardware do when presented with:

char c = 'a';
void *q = &c;
int *p = q;

The same thing. You may be thinking of the requirement that a pointer
to object type may be cast to (void *) and back again later _to the
original type_. That is not happening in this situation.

I program in an environment where this does generate a hardware exception
(but that does not resolve this argument, as it could just be that
this environment is non-conforming)
I don't believe a constraint violation results in undefined behavior,
but IANACLL (xref: 6.5.16.1p1 and 4p1).

It seems to me that the Standard only has something to say on topics
where its constraints are met, so this case is outside of the Standard's
scope, therefore UB. IANACLL either though :)
 
O

Old Wolf

char c = 'a';
Nope, this is a constraint violation and requires a diagnostic. Mere
undefined behaviour doesn't.

This sentence seems to imply that constraint violations
are all UB (otherwise, I fail to understand your use of 'mere')
Only in certain cases, when the incompatible type has looser alignment
requirements. Character pointers (of all three types) can be pointed to
any object. Pointers to unsigned char can even be safely dereferenced
after that. A pointer to int can be safely made to point to a struct
whose first member has type int. It can be even dereferenced, if the
struct member has already been initialised.

I agree totally, but the case in point (pointer to int being made to
point to a char) is not in your list of acceptable pointings.
 
J

James Hu

In said:
[snip]
I don't believe a constraint violation results in undefined behavior,
but IANACLL (xref: 6.5.16.1p1 and 4p1).

I should qualify that with "c.v. doesn't necessarily result in u'd.b.".
[snip]
Like I said, IANACLL, but my understanding was that the behavior of a
constraint violation is unspecified behavior, not undefined behavior.

Since I have only be looking at the assignment operator, this statement
should be restricted to the assignment in question:

char c = 'a';
int *p = &c;

BTW, if it wasn't clear before, my xref's are against C99.
The C standard doesn't classify constraint violations in several
categories. ALL of them have the same effect: a diagnostic is required
after which there are no more requirements from the implementation.
An implementation aborting the translation process after issuing a
required diagnostic would be perfectly conforming.

I think this is true of C89. But, C99 seems to have changed things.

For one thing:

xref 4p2: If a "shall" or "shall not" requirement that appears
outside of a constraint is violated, the behavior is undefined.

And this sentence is repeated in the Appendix the summarizes
undefined behaviors. If a constraint violation implied undefined
behavior, I believe the standard would not have bothered to state
this exception.

As to the particular assignment, there is a curious example in the
standard:

xref 6.5.16.1p6: EXAMPLE3: Consider the fragment:

const char **cpp;
char *p;
const char c = 'A';

cpp = &p; // constraint violation
*cpp = &c; // valid
*p = 0; // valid

The first assignment is unsafe because it would allow the
following valid code to attempt to change the value of the
const object c.

It seems the standard is implying the statement with the constraint
violation still has valid semantics.
If all C compilers failed to translate code *requiring* a diagnostic,
C would be a better known language.

Better known? Perhaps just better...
Far too many incompetents discard
ALL the warnings by default, without trying to understand if they signal
a real problem or not.

This point cannot be made often enough.

-- James
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,142
Messages
2,570,818
Members
47,362
Latest member
eitamoro

Latest Threads

Top