Click to See Complete Forum and Search --> : another compiler bug?


Mitsukai
July 24th, 2006, 05:18 PM
i got the folowing code:

unsigned int val1;
void* ptr1 = (void*)val1;
void* ptr2;
ptr1 += ptr2;


then i get the errors:

'+=' : illegal, right operand has type 'void *'
'+=' : pointer on left; needs integral value on right

1. pointers ARE integers.
2. ptr + ptr works why doesnt ptr += ptr?

is the compiler confused because of the int to ptr? (wich i had to type cast, even though pointers are integral)

Calculator
July 24th, 2006, 05:29 PM
1) False, pointers are not integral.
2) ptr + ptr does not work. (error C2110)
3) You can not perform arithmatic on void pointers anyways

Mitsukai
July 24th, 2006, 05:30 PM
pointers are integral. they store the adress of a function or variable

Mitsukai
July 24th, 2006, 05:32 PM
i geuss its not a compiler bug but rather a bug in the standards.
they dont see the need for an int to ptr and ptr+ptr
but i just had had a situation that i needed to.
forcing to type casting is a bit ugly

Dmitry Zemskov
July 24th, 2006, 05:33 PM
>> 1. pointers ARE integers.

Chars are integers too, in the end.

>> 2. ptr + ptr works why doesnt ptr += ptr?

ptr + ptr works?

What is the sence of adding 2 pointers?

Mitsukai
July 24th, 2006, 05:53 PM
What is the sence of adding 2 pointers?

i will give you a simple example.

struct SA
{
int size;
int* data;
};

void FA(const struct SA& PA, const int new_size)
{
int* tmp_data = new int[new_size];
memcpy(tmp_data, PA.data, (PA.size > new_size) ? new_size : PA.size * sizeof(int));
delete[] data;
PA.data = tmp_data;
PA.size = new_size;
}

int main(void)
{
SA LA;
LA.data = new int[LA.size = 1234];
int* LB = LA.size;
FA(LA, 4321);
LB += LA.data; // we now have position of the added space
delete[] LA.data;
}

Calculator
July 24th, 2006, 06:34 PM
Man, that's an int, not an int * Plus

"ComeauTest.c", line 15: error: identifier "data" is undefined
delete[] data;
^

"ComeauTest.c", line 16: error: expression must be a modifiable lvalue
PA.data = tmp_data;
^

"ComeauTest.c", line 17: error: expression must be a modifiable lvalue
PA.size = new_size;
^

"ComeauTest.c", line 24: error: a value of type "int" cannot be used to initialize
an entity of type "int *"
int* LB = LA.size;
^

"ComeauTest.c", line 26: error: expression must have integral or enum type
LB += LA.data; // we now have position of the added space

wildfrog
July 24th, 2006, 08:04 PM
i geuss its not a compiler bug but rather a bug in the standards.I'm sure it standarized that way for a purpose.

they dont see the need for an int to ptrThat you can do with a reinterpret_cast.

and ptr+ptrHow would that work? Currently you can add an integer to a pointer (not a void one) and it is evaluated somewhat like this:

int* ptr = reinterpret_cast<int*>(0x1000);
int n = 5;

// ptr += n;
ptr = reinterpret_cast<int*>(reinterpret_cast<size_t>(ptr) + sizeof(int) * n);
That is, if you add 5 to the an int*, then the value of int* is increased by sizeof(int) * 5. In other words the pointer will point to the 5. integer following its original value. How would you apply this simple rule when adding two pointers? It's called pointer arithmetic and I'm sure it has been discussed since pre-c++.

You can however subtract two pointers (of same type) from eachother. The rusult, a ptrdiff_t, gives the numbers of elements between the two pointers:

int arr[10];
int* ptrA = &arr[1];
int* ptrB = &arr[5];

ptrdiff_t diff = ptrB - ptrA; // results in 4

Both pointers should be pointing to the same array (but not necessarily within the bound of that array). Why? Because otherwise would have strange effects on your code:

int* ptrA = reinterpret_cast<int*>(0x100);
int* ptrB = reinterpret_cast<int*>(0x102); // different, but not by a complete sizeof(int)

if (ptrA == ptrB)
{
// they're equal (this won't happen)
}

if ((ptrA - ptrB) == 0)
{
// they're equal, strange... this will happen
}



but i just had had a situation that i needed to.
forcing to type casting is a bit uglyFrom what Calculator posted, type casting isn't the worst that could happen to that code... :rolleyes:

- petter

Mitsukai
July 24th, 2006, 08:19 PM
i geuss thats true. i forgot about pointer arithmetic.
but i do not understand this.
it does accept a ptr+=int but not a ptr=int?
maybe i should use an integer and cast it to a pointer than other wise..

Calculator
July 24th, 2006, 08:57 PM
ptr += int makes sense. ptr points to a location in memory. adding to the pointer makes it point to a different place in memory. wildfrog explained how the expression ptr += int will increment the pointer by the sizeof *ptr * int. But the problem is that an int is not a pointer, it is not meant to address memory, even if it has the ability to. The C FAQ explains what I was just about to try to explain very well ;) 10.2 Pointers and Arrays; Pointer Arithmetic (http://c-faq.com/~scs/cclass/notes/sx10b.html)

Mitsukai
July 24th, 2006, 09:24 PM
i will give you a simple example.

struct SA
{
int size;
int* data;
};

void FA(struct SA& PA, const int new_size)
{
int* tmp_data = new int[new_size];
memcpy(tmp_data, PA.data, (PA.size > new_size) ? new_size : PA.size * sizeof(int));
delete[] PA.data;
PA.data = tmp_data;
PA.size = new_size;
}

int main(void)
{
SA LA;
LA.data = new int[LA.size = 1234];
int LB = LA.size * sizeof(int); //int* LB = LA.size;
FA(LA, 4321);
LB += (int)LA.data; // LB += LA.data;
delete[] LA.data;
}

i edited my code (it was just a quick example out of hand)

Mitsukai
July 24th, 2006, 09:34 PM
btw i know how ptrs work =]
the reason behind my dumb post is time, it is 4:43 am heh

wildfrog
July 24th, 2006, 09:41 PM
Yup, it's late (again).


LB += (int)LA.data; // LB += LA.data;

int isn't necessarily large enough to hold a pointer. You should use intptr_t.

- petter

Viorel
July 25th, 2006, 01:31 AM
it does accept a ptr+=int but not a ptr=int?

In my opinion the only int accepted in "ptr = int" is zero, meaning "null pointer":

ptr = 0;
Usually it is defined as NULL:

#define NULL 0 // (from WinDef.h)
. . .
ptr = NULL;

SuperKoko
July 25th, 2006, 05:50 AM
struct SA
{
int size;
int* data;
};

void FA(const struct SA& PA, const int new_size)
{
int* tmp_data = new int[new_size];
memcpy(tmp_data, PA.data, (PA.size > new_size) ? new_size : PA.size * sizeof(int));
delete[] data;
PA.data = tmp_data;
PA.size = new_size;
}

int main(void)
{
SA LA;
LA.data = new int[LA.size = 1234];
int* LB = LA.size;
FA(LA, 4321);
LB += LA.data; // we now have position of the added space
delete[] LA.data;
}


It makse no sense

1. pointers ARE integers.

NO.
Pointers can be represented by integers on all platforms, transforming a non flat memory space in a flat memory space, but the process can be very very SLOW.
You want to impose a particular representation for pointers.

Just think about far pointers on x86-16 platforms.

First, pointers usually have a different size from integers.
It can be greater, or it can be smaller.

You piece of code... How would you expect it to work...
Assuming a x86-32 architecture without sizeof(int)==sizeof(void*), and a FLAT addressing space:

In fact, the only thing I see with your code, is that you are not able to use a typed language.

There exists untyped language, such as B.
BUT.

They are very inefficient (or impossible to implement) on platforms having a non-flat addressing mode (such as x86-16)
They are *still* very inefficient on platforms with a flat memory model.
It's a real problem for such languages to choose a "word" size... Which must be the same for pointers & integers.
That's very problematic on many platforms.
Accessing other things than words (such as individual chars or floating point values) is very inefficent or incredibely error prone or incredibely verbose.


Non-typed language, in a general sense, are incredibely error prone.
Plus, it is very hard for the compiler to optimize things.

Even early C compilers were less weakly typed that what you want.

What's wrong with

int main(void)
{
SA LA;
LA.data = new int[LA.size = 1234];
int LA_old_size = LA.size;
FA(LA, 4321);
int* LB =LA.data + LA_old_size;
delete[] LA.data;
}

NMTop40
July 25th, 2006, 06:13 AM
Adding pointers together is meaningless.

Even if you did cast them to integers and add them, the result would be meaningless.

Let's say that your first pointer is allocated at 0x1000000 and the second at 0x1000010.
So if you add them up you will get 0x2000010. Firstly that might not even be a valid memory address, perhaps your memory space is limited to 0x1FFFFFF. And if 0x2000010 is a valid address what is its significance to you? You have not been allocated that memory space to use for anything.

Adding two pointers in some ways is like adding two coordinates on a map. Like trying to add together London and Amsterdam.