Index: doc/theses/mike_brooks_MMath/programs/hello-md.cfa
===================================================================
--- doc/theses/mike_brooks_MMath/programs/hello-md.cfa	(revision 8bd886e83ef877a2ab3a69217f7d29b068ccb384)
+++ doc/theses/mike_brooks_MMath/programs/hello-md.cfa	(revision a5e268212063c10890d2d82bc90a9fcd3b4ac14c)
@@ -1,12 +1,3 @@
 #include "array.hfa"
-
-
-trait ix( C &, E &, ztype(N) ) {
-    E & ?[?]( C &, ptrdiff_t );
-    void __taglen( tag(C), tag(N) );
-};
-
-forall( ztype(Zn), ztype(S), Timmed &, Tbase & )
-void __taglen( tag(arpk(Zn, S, Timmed, Tbase)), tag(Zn) ) {}
 
 
@@ -38,8 +29,17 @@
 
 
-forall( ztype( N ) )
+
+
+
+
+
+
+
+
+
+forall( [N] )
 void print1d_cstyle( array(float, N) & c );
 
-forall( C &, ztype( N ) | ix( C, float, N ) )
+forall( [N], C & | ar( C, float, N ) )
 void print1d( C & c );
 
@@ -58,7 +58,7 @@
 
 
-forall( ztype( N ) )
+forall( [N] )
 void print1d_cstyle( array(float, N) & c ) {
-    for( i; z(N) ) {
+    for( i; N ) {
         printf("%.1f  ", c[i]);
     }
@@ -78,7 +78,7 @@
 
 
-forall( C &, ztype( N ) | ix( C, float, N ) )
+forall( [N], C & | ar( C, float, N ) )
 void print1d( C & c ) {
-    for( i; z(N) ) {
+    for( i; N ) {
         printf("%.1f  ", c[i]);
     }
@@ -99,9 +99,9 @@
 
 
-void fill( array(float, Z(5), Z(7)) & a ) {
+void fill( array(float, 5, 7) & a ) {
     for ( i; (ptrdiff_t) 5 ) {
         for ( j; 7 ) {
-            a[[i,j]] = 1.0 * i + 0.1 * j;
-            printf("%.1f  ", a[[i,j]]);
+            a[i,j] = 1.0 * i + 0.1 * j;
+            printf("%.1f  ", a[i,j]);
         }
         printf("\n");
@@ -118,5 +118,5 @@
 
 
-array( float, Z(5), Z(7) ) a;
+array( float, 5, 7 ) a;
 fill(a);
 /*
@@ -148,10 +148,10 @@
 
 
-print1d( a[[ 2, all ]] );  // 2.0  2.1  2.2  2.3  2.4  2.5  2.6
-print1d( a[[ all, 3 ]] );  // 0.3  1.3  2.3  3.3  4.3
+print1d( a[ 2, all ] );  // 2.0  2.1  2.2  2.3  2.4  2.5  2.6
+print1d( a[ all, 3 ] );  // 0.3  1.3  2.3  3.3  4.3
 
 
 
-print1d_cstyle( a[[ 2, all ]] );
+print1d_cstyle( a[ 2, all ] );
 
 
@@ -161,7 +161,7 @@
 
 
-#ifdef SHOWERR1
+#ifdef SHOW_ERROR_1
 
-print1d_cstyle( a[[ all, 2 ]] );  // bad
+print1d_cstyle( a[ all, 2 ] );  // bad
 
 #endif
Index: libcfa/src/containers/array.hfa
===================================================================
--- libcfa/src/containers/array.hfa	(revision 8bd886e83ef877a2ab3a69217f7d29b068ccb384)
+++ libcfa/src/containers/array.hfa	(revision a5e268212063c10890d2d82bc90a9fcd3b4ac14c)
@@ -1,2 +1,4 @@
+#pragma once
+
 #include <assert.h>
 
@@ -18,7 +20,12 @@
     // About the choice of integral types offered as subscript overloads:
     // Intent is to cover these use cases:
+    //    a[0]                                                // i : zero_t
+    //    a[1]                                                // i : one_t
+    //    a[2]                                                // i : int
     //    float foo( ptrdiff_t i ) { return a[i]; }           // i : ptrdiff_t
+    //    float foo( size_t i ) { return a[i]; }              // i : size_t
     //    forall( [N] ) ... for( i; N ) { total += a[i]; }    // i : typeof( sizeof(42) )
     //    for( i; 5 ) { total += a[i]; }                      // i : int
+    //
     // It gets complicated by:
     // -  CFA does overloading on concrete types, like int and unsigned int, not on typedefed
@@ -28,9 +35,28 @@
     //    should give them type size_t.
     //
-    //                          gcc -m32         cfa -m32 given bug         gcc -m64
+    //                          gcc -m32         cfa -m32 given bug         gcc -m64 (and cfa)
     // ptrdiff_t                int              int                        long int
     // size_t                   unsigned int     unsigned int               unsigned long int
     // typeof( sizeof(42) )     unsigned int     unsigned long int          unsigned long int
     // int                      int              int                        int
+    //
+    // So the solution must support types {zero_t, one_t, int, unsigned int, long int, unsigned long int}
+    //
+    // The solution cannot rely on implicit conversions (e.g. just have one overload for ptrdiff_t)
+    // because assertion satisfaction requires types to match exacly.  Both higher-dimensional
+    // subscripting and operations on slices use asserted subscript operators.  The test case
+    // array-container/array-sbscr-cases covers the combinations.  Mike beleives that commenting out
+    // any of the current overloads leads to one of those cases failing, either on 64- or 32-bit.
+    // Mike is open to being shown a smaller set of overloads that still passes the test.
+
+    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, zero_t ) {
+        assert( 0 < N );
+        return (Timmed &) a.strides[0];
+    }
+
+    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, one_t ) {
+        assert( 1 < N );
+        return (Timmed &) a.strides[1];
+    }
 
     static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, int i ) {
@@ -77,4 +103,6 @@
         return N;
     }
+
+    static inline void __taglen( tag(arpk(N, S, Timmed, Tbase)), tag(N) ) {}
 
     // workaround #226 (and array relevance thereof demonstrated in mike102/otype-slow-ndims.cfa)
@@ -156,4 +184,11 @@
 #endif
 
+// Available for users to work around Trac #265
+// If `a[...0...]` isn't working, try `a[...ix0...]` instead.
+
+#define ix0 ((ptrdiff_t)0)
+
+
+
 //
 // Rotation
@@ -185,6 +220,24 @@
 //
 
-trait ar(A &, Tv &) {
-    Tv& ?[?]( A&, ptrdiff_t );
-    size_t ?`len( A& );
-};
+// desired:
+// trait ar(A &, Tv &, [N]) {
+//     Tv& ?[?]( A&, zero_t );
+//     Tv& ?[?]( A&, one_t  );
+//     Tv& ?[?]( A&, int    );
+//                   ...
+//     size_t ?`len( A& );
+//     void __taglen( tag(C), tag(N) );
+// };
+
+// working around N's not being accepted as arguments to traits
+
+#define ar(A, Tv, N) {                 \
+    Tv& ?[?]( A&, zero_t );            \
+    Tv& ?[?]( A&, one_t );             \
+    Tv& ?[?]( A&, int );               \
+    Tv& ?[?]( A&, unsigned int );      \
+    Tv& ?[?]( A&, long int );          \
+    Tv& ?[?]( A&, unsigned long int ); \
+    size_t ?`len( A& );                \
+    void __taglen( tag(A), tag(N) );   \
+}
Index: tests/array-container/.expect/array-sbscr-types.txt
===================================================================
--- tests/array-container/.expect/array-sbscr-types.txt	(revision a5e268212063c10890d2d82bc90a9fcd3b4ac14c)
+++ tests/array-container/.expect/array-sbscr-types.txt	(revision a5e268212063c10890d2d82bc90a9fcd3b4ac14c)
@@ -0,0 +1,162 @@
+Simple array
+
+100.3
+100.3
+
+100.0
+100.1
+100.2
+100.3
+100.4
+
+100.0
+100.1
+100.2
+100.3
+
+Via trait
+
+100.3
+100.3
+
+100.0
+100.1
+100.2
+100.3
+100.4
+
+100.0
+100.1
+100.2
+100.3
+
+Simple array, multidim
+
+3.3
+3.3
+3.3
+3.3
+
+0.3
+1.3
+2.3
+3.3
+4.3
+
+0.3
+1.3
+2.3
+3.3
+
+3.0
+3.1
+3.2
+3.3
+
+3.0
+3.1
+3.2
+3.3
+
+Via trait, multidim
+
+3.3
+3.3
+3.3
+3.3
+
+0.3
+1.3
+2.3
+3.3
+4.3
+
+0.3
+1.3
+2.3
+3.3
+
+3.0
+3.1
+3.2
+3.3
+
+3.0
+3.1
+3.2
+3.3
+
+Transposed, Via trait, multidim
+
+3.3
+3.3
+3.3
+3.3
+
+3.0
+3.1
+3.2
+3.3
+
+3.0
+3.1
+3.2
+3.3
+
+0.3
+1.3
+2.3
+3.3
+4.3
+
+0.3
+1.3
+2.3
+3.3
+
+Slice giving Simple array
+
+2.3
+2.3
+
+2.0
+2.1
+2.2
+2.3
+
+2.0
+2.1
+2.2
+2.3
+
+Same slice Via trait
+
+2.3
+2.3
+
+2.0
+2.1
+2.2
+2.3
+
+2.0
+2.1
+2.2
+2.3
+
+Strided slice Via trait
+
+3.2
+3.2
+
+0.2
+1.2
+2.2
+3.2
+4.2
+
+0.2
+1.2
+2.2
+3.2
+
Index: tests/array-container/array-basic.cfa
===================================================================
--- tests/array-container/array-basic.cfa	(revision 8bd886e83ef877a2ab3a69217f7d29b068ccb384)
+++ tests/array-container/array-basic.cfa	(revision a5e268212063c10890d2d82bc90a9fcd3b4ac14c)
@@ -78,8 +78,8 @@
 }
 
-forall( A & | ar(A, float) )
+forall( [N], A & | ar(A, float, N) )
 float total1d_hi( A & a ) {
     float total = 0.0f;
-    for (i; a`len)
+    for (i; N)
         total += a[i];
     return total;
Index: tests/array-container/array-sbscr-types.cfa
===================================================================
--- tests/array-container/array-sbscr-types.cfa	(revision a5e268212063c10890d2d82bc90a9fcd3b4ac14c)
+++ tests/array-container/array-sbscr-types.cfa	(revision a5e268212063c10890d2d82bc90a9fcd3b4ac14c)
@@ -0,0 +1,135 @@
+#include <containers/array.hfa>
+
+// Shows support for many required ways a user can index into a new array.
+//
+// A successful run of this test on 32 bit is necessary, before concluding
+// that a relevant change has good quality.  Even though the test has no 
+// differentiated 64/32-bit versions.
+//
+// Repetition, within this test, beween indexing directly into an `array(...)`
+// and indexing into a `A`, as in `forall(A...|ar(A...))`, represents indexing
+// into a (statically programmer-known) contiguous view, and a (potentially)
+// noncontiguous view, respectively.  Users obtain noncontiguous views by
+// slicing or transposing higher-dimensional arrays.  The limited uses of
+// `a[..., all, ...]` within this test create such situations.  Working via
+// the `ar` trait is the first of two ways that users depend on the array
+// implementation tunneling subscript operators through the CFA assertion
+// system.
+//
+// This test uses the `a[i,j]` form for subscriping higher-dimensional arrays,
+// which is the "new" form, compared with the C-style `a[i][j]` form.  The
+// "new" subscripting form is the second of two ways that users depend on the
+// array implementation tunneling subscript operators through the CFA
+// assertion system.
+//
+// This test covers types and syntactic forms that can convey a numeric value
+// to `a[-]` or `a[-,-,-]`.  The array-md-sbscr-cases test covers combinations
+// of `a[i][j,k]` vs `a[i,j,k]` and `a[all,3][42]` vs `a[42,3]`, though
+// generally using ptrdiff_t-typed variables to convey numeric values.
+
+
+#define show( expr ) printf( "%.1f\n", expr )
+
+#define singleDimTestBody(testName) {                      \
+                                                           \
+    printf(testName "\n\n");                               \
+                                                           \
+    assert( 3 < N );                                       \
+                                                           \
+    show( a[i1] );                                         \
+    show( a[i2] );                                         \
+    printf("\n");                                          \
+                                                           \
+    for( i_dynbounded; N ) show( a[i_dynbounded] );        \
+    printf("\n");                                          \
+                                                           \
+    for( i_stabounded; 4 ) show( a[i_stabounded] );        \
+    printf("\n");                                          \
+}
+
+forall( [N] )
+void test_common_arg_types(array(float, N) & a, ptrdiff_t i1, size_t i2)
+    singleDimTestBody("Simple array")
+
+forall( [N], A& | ar(A, float, N) )
+void test_common_arg_types__via_trait(A & a, ptrdiff_t i1, size_t i2)
+    singleDimTestBody("Via trait")
+
+void do1dimTest() {
+    array(float, 5) a;
+    a[0] = 100.0;
+    a[1] = 100.1;
+    a[2] = 100.2;
+    a[3] = 100.3;
+    a[4] = 100.4;
+
+    test_common_arg_types(a, 3, 3);
+    test_common_arg_types__via_trait(a, 3, 3);
+}
+
+#define multiDimTestBody(testName) {                         \
+                                                             \
+    printf(testName "\n\n");                                 \
+                                                             \
+    assert( 3 < M );                                         \
+    assert( 3 < N );                                         \
+                                                             \
+    show(( a[x1,x1] ));                                      \
+    show(( a[x1,x2] ));                                      \
+    show(( a[x2,x1] ));                                      \
+    show(( a[x2,x2] ));                                      \
+    printf("\n");                                            \
+                                                             \
+    for( i_dynbounded; M ) show(( a[i_dynbounded, 3] ));     \
+    printf("\n");                                            \
+                                                             \
+    for( i_stabounded; 4 ) show(( a[i_stabounded, 3] ));     \
+    printf("\n");                                            \
+                                                             \
+    for( j_dynbounded; N ) show(( a[3, j_dynbounded] ));     \
+    printf("\n");                                            \
+                                                             \
+    for( j_stabounded; 4 ) show(( a[3, j_stabounded] ));     \
+    printf("\n");                                            \
+}
+
+forall( [M], [N] )
+void test_common_arg_types__md(array(float, M, N) & a, ptrdiff_t x1, size_t x2)
+    multiDimTestBody("Simple array, multidim")
+
+
+forall( [M], [N], A_outer &, A_inner & | ar(A_outer, A_inner, M) | ar(A_inner, float, N) )
+void test_common_arg_types__md__via_trait(A_outer & a, ptrdiff_t x1, size_t x2)
+    multiDimTestBody("Via trait, multidim")
+
+
+void doMdimTest() {
+
+    array(float, 5, 4) b;
+    b[ix0,ix0] = 0.0; b[ix0,1] = 0.1; b[ix0,2] = 0.2; b[ix0,3] = 0.3;
+    b[  1,ix0] = 1.0; b[  1,1] = 1.1; b[  1,2] = 1.2; b[  1,3] = 1.3;
+    b[  2,ix0] = 2.0; b[  2,1] = 2.1; b[  2,2] = 2.2; b[  2,3] = 2.3;
+    b[  3,ix0] = 3.0; b[  3,1] = 3.1; b[  3,2] = 3.2; b[  3,3] = 3.3;
+    b[  4,ix0] = 4.0; b[  4,1] = 4.1; b[  4,2] = 4.2; b[  4,3] = 4.3;
+
+    test_common_arg_types__md(b, 3, 3);
+    test_common_arg_types__md__via_trait(b, 3, 3);
+    printf("Transposed, ");
+    test_common_arg_types__md__via_trait(b[all], 3, 3);
+
+    printf("Slice giving ");
+    test_common_arg_types(b[2], 3, 3);
+
+    printf("Same slice ");
+    test_common_arg_types__via_trait(b[2], 3, 3);
+
+    printf("Strided slice ");
+    test_common_arg_types__via_trait(b[all,2], 3, 3);
+}
+
+int main() {
+
+    // can't be inlined in same func due to Trac #175.
+    do1dimTest();
+    doMdimTest();
+}
