Hi,

On Fri, 5 Aug 2011, Ulrich Weigand wrote:

> > However, there are situations like the following where you like to take
> > the decision at runtime:
> > 
> > char cast_3 (char in_pgm, void * p)
> > {
> >      return in_pgm ? (*((char __pgm *) p)) : (*((char *) p));
> > }
> 
> That's really an abuse of "void *" ... if you have an address in the
> Flash space, you should never assign it to a "void *".
> 
> Instead, if you just have a address and you don't know ahead of time
> whether it refers to Flash or RAM space, you ought to hold that number
> in an "int" (or "short" or whatever integer type is most appropriate),
> and then convert from that integer type to either a "char *" or a
> "char __pgm *".

That would leave standard C.  You aren't allowed to construct pointers out 
of random integers.  I'd rather choose to abuse "void*" to be able to 
point into a yet-unspecified address spaces, which becomes specified once 
the void* pointer is converted into a non-void pointer (which it must be 
because you can't dereference a void pointer, hence it does no harm to 
leave its address space unspecified).

That would point to a third address space, call it "undef" :)  It would be 
superset of default and pgm, conversions between undef to {default,pgm} 
are allowed freely (and value preserving, i.e. trivial).  Conversion into 
undef could be rejected.  If they are allowed too, then also conversions 
between default and pgm are possible (via an intermediate step over 
undef), at which point the whole excercise seems a bit pointless and one 
could just as well allow conversions between default and pgm.


Ciao,
Michael.

Reply via email to