A nice macro

Rick Schubert rns at se-sd.NCR.COM
Tue Jul 11 05:38:57 AEST 1989


In article <10420 at socslgw.csl.sony.JUNET> diamond at csl.sony.junet (Norman Diamond) writes:
>In article <2784 at solo8.cs.vu.nl> maart at cs.vu.nl (Maarten Litmaath) writes:
>>>C arrays always begin with subscript 0. ... the solution below seems so
>>>straightforward:
>>>	bar	_foo[HIGH - LOW + 1];
>>>	#define		foo		(_foo - LOW)

>In article <13788 at haddock.ima.isc.com> karl at haddock.ima.isc.com (Karl Heuer) writes:
>>But this is not portable if you're trying to emulate, say, origin-1
>>arrays (LOW==1), since the expression (_foo-1) could be >outside your
>>address space.

>True indeed.  The entire expression would yield a valid location
>(except when the program really does have a subscript error),
>e.g. foo[i] == *((_foo-LOW)+i) would be legal if the compiler were
>permitted to rewrite the expression as *(_foo+(i-LOW)).

>Looks like ANSI has standardized existing practice once again, by
>forbidding compilers from making such a rearrangement.  If permitted,
>maybe this would have become a quality-of-implementation issue.

I'm not sure what existing practice you're flaming, but the problem is NOT
that ANSI forbids compilers from making such a rearrangement.

1. Compilers are allowed to make such rearrangements.  The new rule about
   honoring parentheses still allows the compiler to rearrange expressions
   in certain situations.  For integer arithmetic (including, for the purpose
   of this discussion, pointer arithmetic), associative and commutative laws
   may be used if they do not affect the result; this is the case if either:

	a. no overflow can occur either before or after the rearrangement 

	b. no overflow can occur before the rearrangement, can happen after
           the rearrangement, but silent mod 2^n arithmetic takes place
           (at least as far as the rearrangement of additive operators)

        c. overflow would occur before the rearrangement but not after the
           rearrangement.

   Case c applies to your situation.  ((_foo-LOW)+i) may overflow (i.e.
   (_foo-LOW) may yield an invalid address, whereas (_foo+(i-LOW)) would
   not if `i' is a valid subscript.  The compiler would be allowed to
   make this rearrangement.

2. The problem is that the compiler should not be REQUIRED to make such a
   rearrangement.  In order for the macro to be legal, compilers would be
   required to make this rearrangement on architectures for which computing
   (_foo-LOW) would cause problems.  This would be applying the
   Don't-Do-What-I-Said, Do-What-I-Meant principle.

Disclaimer: I can't believe this topic is still active;
sorry for prolonging it.

-- Rick Schubert (rns at se-sd.sandiego.NCR.COM)



More information about the Comp.lang.c mailing list