Multiplication or Division of pointer is not supported by C language

  • Thread starter karthikbalaguru
  • Start date
P

Phil Carmody

True, I hadn't considered overflow.

You didn't mention adding, either. You only requested more operations,
in particular 'averaging', but not 'adding'. Were such an operation be
provided, it would be the implementation's duty to work out the details
such that it always worked, not yours or Dik's.

Phil
 
R

Richard Tobin

True, I hadn't considered overflow.
[/QUOTE]
You didn't mention adding, either. You only requested more operations,
in particular 'averaging', but not 'adding'. Were such an operation be
provided, it would be the implementation's duty to work out the details
such that it always worked, not yours or Dik's.

Dik was right to guess that I was imagining that addition and division
were the operations provided, with the user implementing averaging as
(p1 + p2) / 2.

-- Richard
 
P

Phil Carmody

You didn't mention adding, either. You only requested more operations,
in particular 'averaging', but not 'adding'. Were such an operation be
provided, it would be the implementation's duty to work out the details
such that it always worked, not yours or Dik's.

Dik was right to guess that I was imagining that addition and division
were the operations provided, with the user implementing averaging as
(p1 + p2) / 2.[/QUOTE]

I took you literally. You asked explicitly for averaging, and averaging
makes perfect sense.

Phil
 
P

Peter Nilsson

Dik T. Winter said:
Suppose a system with the data address space starting
at 0x80000000. Assume p1 and p2 to be char pointers.
 In that case the first can be implemented naively
while the second can not.

Which simply means an implementation should not start
the address space there; or it would require special
addition operators, e.g. the top bit is always set
for certain results; etc...

Note that 1c or sm architectures with no natural
support for unsigned arithmetic may find the
implementation of unsigned integers very difficult.
Nevertheless, the standard imposes that requirement
for conforming implementations.

RISC cpus especially draw no distinction between
address registers and data registers. Even the cpus
that do have instructions to transfer an address
register to a data register.

When C first came about, people where using pointers
for unsigned integer arithmetic. So the concept of
full pointer arithmetic is not crazy, it simply isn't
useful and actually defeats the purpose of high level
language abstraction.

The fact that certain architectures would find it
difficult to implement adds to the reasons for not
doing having pointer arithmetic, but the concept can
be rejected long before you even start considering
such architectures.
 
K

Kaz Kylheku

You didn't mention adding, either. You only requested more operations,
in particular 'averaging', but not 'adding'. Were such an operation be
provided, it would be the implementation's duty to work out the details
such that it always worked, not yours or Dik's.

Dik was right to guess that I was imagining that addition and division
were the operations provided, with the user implementing averaging as
(p1 + p2) / 2.[/QUOTE]

What if (p1 + p2) isn't subject to a division? If you are going to define
addition over a domain, that addition should be meaningful by itself.

What are the constraints for p1 + p2? Do these have to be compatible types?
What is the type of the result? Is it a pointer?

What about overflows? p1 and p2 could be anywhere in the address space.

The concept of interpolating values does not require addition in the domain of
those values.

If you want a position one third between two addresses p1 and p2 within some
object, simply take one third of the delta p2 - p1, and add that to p1.

Adding the two quantities and then dividing is a ``hack'' which only works when
the interpolation is 50%.

If you want the point which is 1/10 between p1 and p2, it's not (p1 + p2)/3 but
rather (9 * p1 + p2) / 10. This is because you're taking 1:9 blend of the
values: 9/10 p1 + 1/10 p2. So now you need multiplication of a pointer by
a number number, unless you are happy writing this as
(p1 + p1 + p1 + p1 + p1 + p1 + p1 + p1 + p1 + p2) / 10.

Somehow, p1 + (p2 - p1) / 10 looks a lot better.

In fact, it's better to interpolate integers this way, not only pointers,
because of the avoidance of overflow.

E.g.

/* update smoothed estimator,
blending 75% of the old value with 25% of the sample */

smoothed_estimator += (new_sample - smoothed_estimator) / 4;

You'd not want to do this using:

smoothed_estimator = (3 * smoothed_estimator + new_sample) / 4
 
R

Richard Tobin

Kaz Kylheku said:
What if (p1 + p2) isn't subject to a division? If you are going to define
addition over a domain, that addition should be meaningful by itself.
Why?

What are the constraints for p1 + p2? Do these have to be compatible types?

Up to you. I don't propose to fully design a feature with such little
utility.
What is the type of the result?

For example, "sum of int * and char *".
Is it a pointer?

Of course not.
What about overflows? p1 and p2 could be anywhere in the address space.

The implementation has to use a reasonable size, just as it does
for integers.
The concept of interpolating values does not require addition in the domain of
those values.

As I have made clear already. You seem to be searching for a straw
man to attack.
If you want a position one third between two addresses p1 and p2 within some
object, simply take one third of the delta p2 - p1, and add that to p1.

Adding the two quantities and then dividing is a ``hack'' which only works when
the interpolation is 50%.

On the contrary, having to convert to offsets is a hack.
If you want the point which is 1/10 between p1 and p2, it's not (p1 + p2)/3 but
rather (9 * p1 + p2) / 10. This is because you're taking 1:9 blend of the
values: 9/10 p1 + 1/10 p2. So now you need multiplication of a pointer by
a number number

See, you have no trouble coming up with applications for pointer
multiplication.

-- Richard
 
C

CBFalconer

.... snip ...

But, but, but.. Richard-I-single-step-all-my-code says that
pointers are addresses are integers and you multiply integers so
you *must* be able to multiply pointers!

But pointers are not addresses which in turn are not integers.
Pointers and addresses may include other fields. Such as "look in
little Johnnys back pocket for the nth piece of paper and read off
the kth line on that". All they have to do is lead to the data to
which they point.
 
B

Ben Bacarisse

CBFalconer said:
But pointers are not addresses which in turn are not integers.
Pointers and addresses may include other fields.

That addresses and pointers are not numbers is plain enough, but you'd
have a harder time arguing that pointers are not addresses in a C
group. The standard uses the term address to mean the values held in
pointer variables. & is the address operator whose result is of type
"pointer to ...". Address constants can be used to initialise pointer
variables.

Of course there are not identical terms, but pointer objects hold
addresses like int objects hold numbers.
 
G

Guest

Would you like to quote that with context please.

I thought you had said that pointers were integers at some point.
If I have misrepresented you then I withdraw the remark.
Or are you being typically ignorant and small minded?

oh, a poor attempt at humour. But then Chuck didn't get it either.

<snip>
 
B

Bruce Cook

Dik said:
p1 + (p2 - p1)/2

On the other hand, naive adding two pointers and dividing by 2 would not
result in a valid pointer on some machines.

Shudder !

Some of us have used architectures with segment:eek:ffset pointers (think 286).
Subtraction of pointers would be... interesting, and not very useful.

Bruce
 
R

Richard Tobin

Bruce Cook said:
Some of us have used architectures with segment:eek:ffset pointers (think 286).

Some of us rejected the whole x86 family until the 386 came along.
Subtraction of pointers would be... interesting, and not very useful.

Subtraction of pointers is already allowed, but they are constrained
to be pointers into the same object, which is precisely to accomodate
non-linear address spaces.

-- Richard
 
N

Nate Eldredge

Anthony Fremont said:
All Intel x86 processors (since the 8086) support that silly format in
"real" mode. It's not difficult to convert a seg:para combination into a
20bit address that can easily be compared or subtracted. Of course this is
all moot now since no one runs their x86 processor in real mode any more
(excepting the millions of pc104 embedded systems around the world running
DOS and turbo C apps).

This is true for real mode. But the 286 also had a protected mode,
where the "segment" wasn't just the high bits of a 20-bit address, but
an index ("selector") into a descriptor table which contained the
physical location of the region in question (which the operating system
could adjust transparently as segments were swapped in and out). The
offset was still 16 bits, so a program needing more than 64K of data
would have several segments allocated to it. It would use 32-bit
segment:eek:ffset pointers, but I suppose arithmetic would be done using
the offset alone (I've never programmed in C on protected-mode 286).
There would be no meaningful way to compare or subtract pointers
referring to different segments.

The 386 and successors retain a similar feature, with 16-bit segments
and 32-bit offsets, but most systems sensibly avoid using it, and
provide a flat 32-bit address space by using a single segment for
everything. The segment is implicit in all references, and a pointer
consists only of the 32-bit offset.
 
R

Richard Bos

Antoninus Twink said:
It's surprising that Bjarn Strostroup didn't find some counter-intuitive
and confusing interpretation of an overloaded multiplication operator on
pointers - if he couldn't do it, who else can?...

To be fair to him, he was probably too busy adding useless casts.

Richard
 
K

Kaz Kylheku

Some of us rejected C until the C90 spec. came out.

Really? Has it in fact been 19 years that you've been blundering your way in
this language?

Kids that weren't even born then can code circles around Chucky today.
 
N

Nate Eldredge

Anthony Fremont said:
I don't know much about the later procs, but don't they work pretty much the
same way? The "segment" is just the offset into a page table?

Not a page table, but a descriptor table. The page table is something
else.

The CPU starts with a "virtual address" consisting of a 16-bit selector
(what I've sloppily referred to as the "segment") and a 32-bit offset.
The selector is used as an index into a descriptor table, indicating an
entry which contains a base address, a limit, and some permission
information. The base address plus the offset gives a 32-bit "linear
address". The linear address is then looked up in a multi-level page
table to find a physical address.
With access to the page tables you could find the physical address
difference, but it would be completely meaningless to most C programs.
OTOH, an OS might care for some reason. At any rate, C requires the
pointers point to the same object so .....

s/page/descriptor/

Perhaps, but the operating system can move segments around at will,
invisibly to the application, so long as it keeps the descriptor tables
in sync. So the physical address might change before you are finished
with it, leading to paradoxical results. Or, if the pointer refers to a
segment that has been swapped out, there might not be a physical address
corresponding to it at all.
 
K

Keith Thompson

rio said:
if you know that p2>=p1 ok but
if p2<p1 this above for me is wrong better in that case:

p1+(p1>p2?(p1-p2)/2:(p2-p1)/2);

It may be wrong for you, but it's ok as far as the language is
concerned. Pointer subtraction yields a result of type ptrdiff_t,
which is signed, and it's perfectly legitimate for it to yield a
negative value.
 
D

Dik T. Winter

> "Dik T. Winter" <[email protected]> ha scritto nel messaggio
> news:[email protected]... ....
>
> if you know that p2>=p1 ok but
> if p2<p1 this above for me is wrong better in that case:
>
> p1+(p1>p2?(p1-p2)/2:(p2-p1)/2);

Why is that better? I would state that that is entirely wrong! In your
expression when p2 < p1, the result can be larger than p1, while it should
be smaller.
 

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

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top