F2C translated code breaks when optimized by C++ compiler -
i have c++ program method looks this:
int mymethod(int* arr1, int* arr2, int* index) { arr1--; arr2--; int val = arr1[*index]; int val2 = arr2[val]; return domorethings(val); } with optimizations enabled (/o2) first line first pointer decremented not executed. i'm debugging optimized , non optimized builds side side , optimized build steps on decrement, while non-optimized program executes it. produces observable difference in behavior when later accesses array arr[*index].
update
as @stefaanv pointed out, decrement may indeed omitted compiler, if instead changes decremented access index, appears do. omitted decrement not causing difference in behavior. instead, there in use of matrices causes it.
looking further have narrowed down method contains nested loops performing matrix multiplication. part of method looks this: 3 arrays involved: a, wa , t. in beginning of method f2c translator uses decrement array 6 6 in fortran flat double[36] in c. able use old indexing, moves array pointers number of columns in matrix.
normally in f2c translated program, flat arrays passed &somearray[1] , methods begin decrementing each array one. @christoph pointed out should valid, array never decremented beyond declared range.
in case of method, arrays passed in not passed pointer element further array &somearray[1] here arrays local static arrays declared fixed size e.g. mat[36] , passed directly multiplication method.
void test() { double mat[36]; ... mul(mat, .., ..) } void mul(double* a, double* t, double*wa, int m, int n, int k) { // f2c array decrements. -= (1+m); // e.g. decrement 7 a[6x6]! t -= (1+n); wa--; ... (j = k; j <= m; ++j) { (i = 1; <= n; ++i) { ii = k; wa[i] = 0.; (p = 1; p <= n; ++p) { wa[i] += t[p + * t_dim1] * a[ii + j * a_dim1]; ++ii; } } ii = k; (i = 1; <= n; ++i) { a[ii + j * a_dim1] = wa[i]; if (j > kn) { a[j + ii * a_dim1] = wa[i]; } ++ii; } } } so question is:
does mean behavior undefined , may break under optimization when f2c has done here, i.e subtract 7 double[36] array pointer access items in array in correct locations (offset 7)?
edit: found in c faq, apply here?
pointer arithmetic defined long pointer points within same allocated block of memory, or imaginary "terminating" element 1 past it; otherwise, behavior undefined, even if pointer not dereferenced. .... references: k&r2 sec. 5.3 p. 100, sec. 5.4 pp. 102-3, sec. a7.7 pp. 205-6; iso sec. 6.3.6; rationale sec. 3.2.2.3.
update 2:
if recompile multidimensional arrays using decremented indices rather decremented pointers,
#define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1 - 1 - a_dim1] a_ref(1,2); then method produces same (expected) output regardless of optimizations. single dimensional arrays decremented 1 appear not create issues.
i change multi dimensional arrays in program using above access method, single dim arrays many change manually, ideally solution works both.
new questions:
- is there option f2c use array access method rather pointer fiddling? seems simple change in f2c, , produce defined code, think options.
- are there other solutions problem (other skipping optimizations , hoping program behaved, despite relying on undefined behavior).
- is there can in c++ compiler? compile microsoft c++ (2010), managed c++ project.
the optimizer should make sure there no observable behavior change, can choose not decrement , access data decremented index (the offset can part of opcode) because function uses copy of pointer array. don't tell how array accessed , whether optimizer introducing error, can guess this.
but slartibartfast said: undefined behavior decrement should replaced int val = arr1[*index-1]; after checking *index > 0
Comments
Post a Comment