Signed Unsigned problem

C

candy_init

Hi,

The comparison between signed and unsigned results in the signed
quantity being made as
unsigned. Therefore, in the code:

unsigned int i = 0;
int len = -1;
for(i =0; i < len; ++i)
{
}

the loop will run a lot many times.

now consider the following code:

int funct()
{
int data[10];
data[-1] = 2;
return 0;
}

now data is equivalent to data + i * sizeof(int). Here since
sizeof returns unsigned,
therefore, data[-1] should always seek a value at an index more than
starting index 0.
But in reality, data[-1] does returns the value from the index which
is 1 before the starting
index.
So, can anyone please correct me where I am wrong?

Thanks
 
R

Richard Heathfield

(e-mail address removed) said:

now consider the following code:

int funct()
{
int data[10];
data[-1] = 2;
return 0;
}

now data is equivalent to data + i * sizeof(int). Here since
sizeof returns unsigned,


Actually, the C Standard doesn't say anything of the kind. It does say that
data is equivalent to *(data + i), but it says nothing about the
signedness of the type of i.
therefore, data[-1] should always seek a value at an index more than
starting index 0.

C doesn't guarantee that; the behaviour on accessing a non-existent element
of an array is undefined.
But in reality, data[-1] does returns the value from the index which
is 1 before the starting index.

C doesn't guarantee that; the behaviour on accessing a non-existent element
of an array is undefined.
So, can anyone please correct me where I am wrong?

You are wrong in trying to determine knowledge about C by observing the
effect of incorrect code. This is rather like trying to learn Spanish by
looking up Spanish words at random in a Spanish-only dictionary, saying
them at a Spaniard, and observing his reaction.
 
P

Philip Potter

Richard said:
(e-mail address removed) said:
now consider the following code:

int funct()
{
int data[10];
data[-1] = 2;
return 0;
}

now data is equivalent to data + i * sizeof(int). Here since
sizeof returns unsigned,


Actually, the C Standard doesn't say anything of the kind. It does say that
data is equivalent to *(data + i), but it says nothing about the
signedness of the type of i.


Indeed, and the value in square brackets need not be of integer type (as
in i[data]) and so signedness may not be a meaningful concept for it.

The reason the sizeof(int) term is not only not needed but is incorrect
is because pointer arithmetic is done in steps of the size of the
pointed-to type.

void *data = malloc(128); /* assumes sizeof(int, long double) <=128 */
int *intp = data;
char *charp = data;
long double *ldp = data;
intp[1] = 1234; /* advances one 'int' beyond data */
charp[1] = 'A'; /* advances one 'char' beyond data */
ldp[1] = 1.234L; /* advances one 'long double' beyond data */
data[1] = 'A'; /* error; with type 'void', how far do you advance? */
free(data); /* because this example is responsible :) */
therefore, data[-1] should always seek a value at an index more than
starting index 0.

C doesn't guarantee that; the behaviour on accessing a non-existent element
of an array is undefined.
But in reality, data[-1] does returns the value from the index which
is 1 before the starting index.

C doesn't guarantee that; the behaviour on accessing a non-existent element
of an array is undefined.

This is true. Returning to well-defined C, the OP's questions could
reasonably be asked about the following:
int *data = malloc(128 * sizeof *int);
int *intp = data + 10;
intp[-1] = 1234;

which will work exactly the same as

data[9] = 1234;

And let us not forget

free(data);
You are wrong in trying to determine knowledge about C by observing the
effect of incorrect code. This is rather like trying to learn Spanish by
looking up Spanish words at random in a Spanish-only dictionary, saying
them at a Spaniard, and observing his reaction.

Are Spaniards known for their friendship with nasal demons?
 
M

Martin Ambuhl

now consider the following code:

int funct()
{
int data[10];
data[-1] = 2;
^^^^^^^^
This is illegal, so any question based on this assignment is not
worth considering.
 
D

David Tiktin

(e-mail address removed) said:

now consider the following code:

int funct()
{
int data[10];
data[-1] = 2;
return 0;
}

now data is equivalent to data + i * sizeof(int). Here since
sizeof returns unsigned,


Actually, the C Standard doesn't say anything of the kind. It does
say that data is equivalent to *(data + i), but it says nothing
about the signedness of the type of i.
therefore, data[-1] should always seek a value at an index more
than
starting index 0.

C doesn't guarantee that; the behaviour on accessing a
non-existent element of an array is undefined.
But in reality, data[-1] does returns the value from the index
which
is 1 before the starting index.

C doesn't guarantee that; the behaviour on accessing a
non-existent element of an array is undefined.


OK, point well taken, but perhaps the OP would still have a question
about this code:

int funct()
{
int data[10] = { 0 };
int * ptr = data;

ptr++;

assert(&ptr[-1] == &data[0]);

ptr[-1] = 2;

return 0;
}

In other words, does the standard guarantee that the assert will not
fire? (Assuming, of course, that NDEBUG is not defined ;-)

Dave
 
S

santosh

David said:
C doesn't guarantee that; the behaviour on accessing a
non-existent element of an array is undefined.

OK, point well taken, but perhaps the OP would still have a question
about this code:

int funct()
{
int data[10] = { 0 };
int * ptr = data;

ptr++;

assert(&ptr[-1] == &data[0]);

ptr[-1] = 2;

return 0;
}

In other words, does the standard guarantee that the assert will not
fire? (Assuming, of course, that NDEBUG is not defined ;-)

I think so, since this code is accessing an existing element of the
array.
 
P

Philip Potter

santosh said:
David said:
C doesn't guarantee that; the behaviour on accessing a
non-existent element of an array is undefined.
OK, point well taken, but perhaps the OP would still have a question
about this code:

int funct()
{
int data[10] = { 0 };
int * ptr = data;

ptr++;

assert(&ptr[-1] == &data[0]);

ptr[-1] = 2;

return 0;
}

In other words, does the standard guarantee that the assert will not
fire? (Assuming, of course, that NDEBUG is not defined ;-)

I think so, since this code is accessing an existing element of the
array.
Nitpick: the assert (which David Tiktin was asking about) does not
access any elements of any array. But it doesn't calculate any address
which it isn't allowed to calculate either, so everything should be fine.
 
S

santosh

Philip said:
santosh said:
David said:
On 19 Dec 2007, Richard Heathfield <[email protected]> wrote:

C doesn't guarantee that; the behaviour on accessing a
non-existent element of an array is undefined.
OK, point well taken, but perhaps the OP would still have a question
about this code:

int funct()
{
int data[10] = { 0 };
int * ptr = data;

ptr++;

assert(&ptr[-1] == &data[0]);

ptr[-1] = 2;

return 0;
}

In other words, does the standard guarantee that the assert will not
fire? (Assuming, of course, that NDEBUG is not defined ;-)

I think so, since this code is accessing an existing element of the
array.
Nitpick: the assert (which David Tiktin was asking about) does not
access any elements of any array. But it doesn't calculate any address
which it isn't allowed to calculate either, so everything should be
fine.

Okay. The assert is valid for the same reason that the next assignment
is valid. This is more confusing because we are mixing pointers with
array notation. But of course, this is impossible to avoid in C.
 

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
473,769
Messages
2,569,582
Members
45,069
Latest member
SimplyleanKetoReviews

Latest Threads

Top