:: Re: [DNG] Making sense of C pointer…
Αρχική Σελίδα
Delete this message
Reply to this message
Συντάκτης: Rainer Weikusat
Ημερομηνία:  
Προς: dng
Αντικείμενο: Re: [DNG] Making sense of C pointer syntax.
Edward Bartolo <edbarx@???> writes:
> Hi,
>
> Thanks for dedicating some of your time to answer me. I used:
>
> void change_value(void** ptr)
>
> Because I wanted to enable myself to allocate memory for the pointer
> inside the function, therefore I needed a pointer to a pointer of type
> void.


This is a wrong assumption and it relies on behaviour the C standard
doesn't guarantee. Any pointer may be converted (it's even converted
automatically as required) to a void * and back and

"the result shall compare equal to the original pointer"

But a pointer to a void * is an entirely different animal and no such
guarantees are made for that. This will work in practice if there's only
one 'machine pointer type' anyway, though. But using it is not necessary
as void * is sufficient.

----
#include <stdio.h>
#include <stdlib.h>

enum {
    CHAR =    1,
    SHORT =    sizeof(short),
    INT =    sizeof(int),
    LLONG =    sizeof(long long)
};


static void alloc_int(void *p, int which)
{
    void *area;


    area = malloc(which);
    switch (which) {
    case CHAR:
    *(char **)p = area;
    break;


    case SHORT:
    *(short **)p = area;
    break;


    case INT:
    *(int **)p = area;
    break;


    case LLONG:
    *(long long **)p = area;
    }
}


int main(void)
{
    unsigned long long *pll;


    alloc_int(&pll, LLONG);
    *pll = -1;
    printf("%llx\n", *pll);


    return 0;
}
----


NB: That's seriously bizarre code.    


[...]

> This is a program employing the use of a pointer to change the value
> of a parameter inside a function.
>
> #include <stdio.h>
> #include <stdlib.h>
>
> int afunc(double* dd) {
> *dd *= 2;
> }


There's a return statement missing here or the declared return value is
wrong. It's a good idea to enable compiler warnings when compiling as
this means the compiler will - well - warn about such issues:

[rw@doppelsaurus]/tmp#gcc -W -Wall b.c
b.c: In function 'afunc':
b.c:6:1: warning: control reaches end of non-void function [-Wreturn-type]

Also, to state this again: C is not Pascal and doesn't distinguish
between 'subprograms which may return values and should/ must not have
side effects' (function) and 'subprograms which are executed for the
side effects but cannot return values except by using output
parameters'. When you're writing C, use the return value to return
values, eg

double afunc(double in)
{
    return in * 2;
}        


[...]

> The reason for this is the fact that a pointer is a number.


A machine address may be a number but a pointer isn't. That's something
abstract defined by C as having certain properties. Among these are that
pointers may be converted to integers and vice versa but the effect is
implementation dependent and the behaviour may be undefined. Again,
provided the integer has a sufficient size, this will usually
work. There are also optional types intptr_t and uintptr_t guaranteed to
be capable of storing the value of a void *.