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

int pointing to char

P: n/a
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
Nov 14 '05 #1
Share this Question
Share on Google+
23 Replies


P: n/a
On 2004-03-03, Gautam <ga********@yahoo.com> wrote:
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
Nov 14 '05 #2

P: n/a
In <44*************************@posting.google.com> ga********@yahoo.com (Gautam) writes:
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?
getch();
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
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #3

P: n/a
Gautam wrote:

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.
getch();
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.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #4

P: n/a
James Hu wrote:
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... :-(
Nov 14 '05 #5

P: n/a
In article <40***********************@news.free.fr>,
gregg <gr******@netJUSTSAYNOcourrier.com> wrote:
James Hu wrote:
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 ?


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.
I'm a bit confused with terminology here... :-(


Nov 14 '05 #6

P: n/a
Gautam wrote:
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;
}
Nov 14 '05 #7

P: n/a
Clark Cox wrote:
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.
Nov 14 '05 #8

P: n/a
> > 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 !

#include <stdio.h>

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

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

. . . . 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()",
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.
Nov 14 '05 #9

P: n/a
On 2004-03-04, Old Wolf <ol*****@inspire.net.nz> wrote:
> 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 !
> #include <stdio.h>
>
> void main()
> {
> char c = 'a';
> int * p;
>
> p = &c; /*suspicious pointer conversion WARNING !*/
> clrscr();
> pf("\n%d", *p);
> getch();
> }

> . . . . 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.
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
Nov 14 '05 #10

P: n/a
James Hu wrote:

On 2004-03-04, Old Wolf <ol*****@inspire.net.nz> wrote:
> 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 !

> #include <stdio.h>
>
> void main()
> {
> char c = 'a';
> int * p;
>
> p = &c; /*suspicious pointer conversion WARNING !*/
> clrscr();
> pf("\n%d", *p);
> getch();
> }

> . . . . 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.
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).


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

--
pete
Nov 14 '05 #11

P: n/a
In <84**************************@posting.google.com > ol*****@inspire.net.nz (Old Wolf) writes:
> 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 !
> #include <stdio.h>
>
> void main()
> {
> char c = 'a';
> int * p;
>
> p = &c; /*suspicious pointer conversion WARNING !*/
> clrscr();
> pf("\n%d", *p);
> getch();
> }

> . . . . 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()",
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
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #12

P: n/a
In <40***********@mindspring.com> pete <pf*****@mindspring.com> writes:
James Hu wrote:

On 2004-03-04, Old Wolf <ol*****@inspire.net.nz> wrote:
> 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).


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
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #13

P: n/a
On 2004-03-04, Dan Pop <Da*****@cern.ch> wrote:
In <40***********@mindspring.com> pete <pf*****@mindspring.com> writes:
James Hu wrote:

On 2004-03-04, Old Wolf <ol*****@inspire.net.nz> wrote:

> 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).


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.


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

P: n/a
On 2004-03-04, James Hu <jx*@despammed.com> wrote:
On 2004-03-04, Dan Pop <Da*****@cern.ch> wrote:
In <40***********@mindspring.com> pete <pf*****@mindspring.com> writes:
James Hu wrote:

On 2004-03-04, Old Wolf <ol*****@inspire.net.nz> wrote:

> 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).
I should qualify that with "c.v. doesn't necessarily result in u'd.b.".
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.


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

P: n/a
In <N7********************@comcast.com> James Hu <jx*@despammed.com> writes:
On 2004-03-04, Dan Pop <Da*****@cern.ch> wrote:
In <40***********@mindspring.com> pete <pf*****@mindspring.com> writes:
James Hu wrote:

On 2004-03-04, Old Wolf <ol*****@inspire.net.nz> wrote:

> 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).

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.


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[b] 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
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #16

P: n/a
In <Uo********************@comcast.com> James Hu <jx*@despammed.com> writes:
On 2004-03-04, James Hu <jx*@despammed.com> wrote:
On 2004-03-04, Dan Pop <Da*****@cern.ch> wrote:
In <40***********@mindspring.com> pete <pf*****@mindspring.com> writes:

James Hu wrote:
>
> On 2004-03-04, Old Wolf <ol*****@inspire.net.nz> wrote:
>
> > 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).
I should qualify that with "c.v. doesn't necessarily result in u'd.b.".
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.


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;


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
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #17

P: n/a
> >> > 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.
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;


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 :)
Nov 14 '05 #18

P: n/a
> >> > char c = 'a';
> int * p;
>
> p = &c; /*suspicious pointer conversion WARNING !*/
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.


This sentence seems to imply that constraint violations
are all UB (otherwise, I fail to understand your use of 'mere')
(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.


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.
Nov 14 '05 #19

P: n/a
On 2004-03-04, Dan Pop <Da*****@cern.ch> wrote:
In <Uo********************@comcast.com> James Hu <jx*@despammed.com> writes:
On 2004-03-04, James Hu <jx*@despammed.com> wrote:
>> [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
Nov 14 '05 #20

P: n/a
On 2004-03-04, Old Wolf <ol*****@inspire.net.nz> wrote:
I wrote:
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.


Yikes. I didn't really mean ignore (my original response to the OP
did not ignore it). I meant I generally discount it as a source of
erroneous behavior.

-- James
Nov 14 '05 #21

P: n/a
In <8M********************@comcast.com> James Hu <jx*@despammed.com> writes:
On 2004-03-04, Dan Pop <Da*****@cern.ch> wrote:
In <Uo********************@comcast.com> James Hu <jx*@despammed.com> writes:
On 2004-03-04, James Hu <jx*@despammed.com> wrote:
>>>[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;
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.


Nope, C99 hasn't changed anything here. ALL constraint violations are
treated identically by C99, as well.
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.
Please engage your brain. Undefined behaviour as such does NOT require
a diagnostic. Hence the distinction: violating a shall inside a
constraint requires a diagnostic, violating a shall outside a constraint
doesn't.

The standard stil doesn't provide any clue about the behaviour of a
program violating a constraint, unless you can prove otherwise.
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.


That would be the case if the text said "because it allows the following".
As it is, the standard explains the semantics if the statement in question
were allowed by the language.

The standard explains why the statement is not actually allowed in
correct C programs. A compiler is not required to translate such code,
which wouldn't be the case if the code had valid semantics.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #22

P: n/a
In <84**************************@posting.google.com > ol*****@inspire.net.nz (Old Wolf) writes:
>> > char c = 'a';
>> > int * p;
>> >
>> > p = &c; /*suspicious pointer conversion WARNING !*/

>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.


This sentence seems to imply that constraint violations
are all UB (otherwise, I fail to understand your use of 'mere')


AFTER the reqired diagnostic is produced. Big difference!
>(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.


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.


I was addressing your sweeping generalisation underlined above,
that has precious little to do with the case in point. However, even the
case in point is perfectly OK on implementations where all types have
identical alignment requirements. That is, assuming that the required
cast is present.

Anyway, here is the chapter and verse:

7 A pointer to an object or incomplete type may be converted to
a pointer to a different object or incomplete type. If the
resulting pointer is not correctly aligned for the pointed-to
type, the behavior is undefined.

Doesn't quite match your statement, does it?

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #23

P: n/a
On 2004-03-05, Dan Pop <Da*****@cern.ch> wrote:
In <8M********************@comcast.com> James Hu <jx*@despammed.com> writes:
[snip]
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.
Please engage your brain.


I have given you the benefit of the doubt. But even if I had not,
I would still give you the courtesy of keeping the sentiment to
myself.
Undefined behaviour as such does NOT require a diagnostic. Hence
the distinction: violating a shall inside a constraint requires a
diagnostic, violating a shall outside a constraint doesn't.
There is no need to make that distinction with the wording that I
quoted. 5.1.1.3 already makes it clear a constraint violation
requires a diagnostic, even in the cases it is explicitly stated
to cause undefined behavior. The quote:

xref 5.1.1.3p1: A conforming implementation shall produce at least
one diagnostic message ... if a preprocessing translation unit or
translation unit contains a violation of any syntax rule or constraint,
even if the behavior is also explicitly specified as undefined or
implementation-defined.

So, if the sentence I cited in 4p2 just drops "that appears outside
of a constraint", a diagnostic would still be required for a constraint
violation. Instead, the standard clearly draws a line, as if to say
constraint violations do not necessarily imply undefined behavior.
The standard stil doesn't provide any clue about the behaviour of a
program violating a constraint, unless you can prove otherwise.


I have changed my mind. It is not unspecified behavior. My deduction
is now that the standard is realizing that a program with a constraint
violation may not exhibit any behavior whatsoever. Only if the
constraint violation also violates syntax or violates semantics does the
behavior of the program become undefined.

The example in 5.1.1.3 points to this:

xref 5.1.1.3p2: EXAMPLE An implementation shall issue a diagnostic
for the translation unit:

char i;
int i;

because in those cases where the wording in this International
Standard describes the behavior for a construct as being both
a constraint error and resulting in undefined behavior, the
constraint error shall be diagnosed.

The constraint error in this case is a violation of 6.7p3. But the
undefined behavior is the consequence of the defined semantics in
6.7.5p2.
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.


That would be the case if the text said "because it allows the following".
As it is, the standard explains the semantics if the statement in question
were allowed by the language.

The standard explains why the statement is not actually allowed in
correct C programs. A compiler is not required to translate such code,
which wouldn't be the case if the code had valid semantics.


If the result of the constraint violation is undefined behavior, what
does it matter what the hypothetical semantics of it and following
statements would be? I don't think the standard would waste time
discussing hypothetical semantics, as such discussions should be
left in footnotes and rationales. The semantics are real, as if the
pointer conversion of the RHS was coerced via an implicit cast.

-- James
Nov 14 '05 #24

This discussion thread is closed

Replies have been disabled for this discussion.