首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >由F2C编译器优化时,C++翻译的代码中断

由F2C编译器优化时,C++翻译的代码中断
EN

Stack Overflow用户
提问于 2012-06-05 10:37:15
回答 2查看 394关注 0票数 2

我有一个c++程序,它的方法如下所示:

代码语言:javascript
复制
int myMethod(int* arr1, int* arr2, int* index)
{
    arr1--;        
    arr2--;
    int val = arr1[*index];
    int val2 = arr2[val];
    return doMoreThings(val);
}

在启用优化(/O2)的情况下,不会执行第一个指针减少的第一行。我正在同时调试优化的和非优化的构建,优化的构建步骤通过减少,而非优化的程序执行它。这在以后使用arr*index访问数组时会产生明显的行为差异。

更新

正如@stefaanv所指出的,如果编译器更改为递减的访问索引(它似乎是这样做的),则编译器确实可以省略该减量。因此,省略的减少并不是导致行为差异的原因。相反,在矩阵的使用中有一些东西导致了它。

再看一看,我把范围缩小到一个包含执行矩阵乘法的嵌套循环的方法。该方法的部分内容如下:涉及3个数组: a、wa和t。在该方法的开头,f2c转换器使用了一个递减,以便在fortran中为6乘6的数组是c中的平面double[36]。但是为了能够使用旧的索引,它将数组指针按矩阵中的列数向后移动。

通常,在这个f2c翻译的程序中,平面数组是以&someArray[1]的形式传递的,方法从每一个数组的递减开始。@Christoph指出,这应该是有效的,因为数组的递减永远不会超出其声明的范围。

在这种方法中,传入的数组不是作为指向元素的指针传递到数组&someArray[1]中,而是在这里,数组是以固定大小声明的本地静态数组,例如mat[36],并直接传递给乘法方法。

代码语言:javascript
复制
void test()
{
    double mat[36];
    ...
    mul(mat, .., ..)
}

void mul(double* a, double* t, double*wa, int M, int N, int K)
{
    // F2C array decrements.
    a -= (1+M); // E.g. decrement by seven for a[6x6]!
    t -= (1+N); 
    wa--;
    ...
    for (j = K; j <= M; ++j) {         
       for (i = 1; i <= N; ++i) {
          ii = K;
          wa[i] = 0.;          
          for (p = 1; p <= N; ++p) {
             wa[i] += t[p + i * t_dim1] * a[ii + j * a_dim1];
             ++ii;
          }
       }

       ii = K;      
       for (i = 1; i <= N; ++i) {
          a[ii + j * a_dim1] = wa[i];
          if (j > kn) {
             a[j + ii * a_dim1] = wa[i];
          }
          ++ii;
      }
    }
 }    

所以问题是:

这是否意味着行为是未定义的,并且在执行f2c在这里所做的操作时可能会中断,即从double36数组指针中减去7,然后在正确的位置访问数组中的所有项(偏移量7)?

编辑:在C常见问题中找到了这个,这适用于这里吗?

指针算法只在指针指向同一分配内存块内的指针,或指向经过该块内存的假想“终止”元素时才定义;否则,即使指针未被取消引用,行为也是未定义的。……参考文献: K&R2,Sec.5.3第100页,证券交易委员会。5.4第102-3页,证券交易委员会。A7.7第205-6页;ISO Sec。6.3.6;理由证券分节。3.2.2.3.

更新2:

如果我使用递减索引而不是递减指针重新编译多维数组,

代码语言:javascript
复制
#define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1 - 1 - a_dim1]

a_ref(1,2);

然后,不管优化如何,该方法都会产生相同的(预期的)输出。单维数组(仅由一个数组递减)似乎不会产生任何问题。

我可以将程序中的所有多维数组更改为使用上面的访问方法,但是单个昏暗数组的数量太多,无法手动更改,因此理想情况下,我希望有一个对两者都适用的解决方案。

新问题:

  • 是否有选项让f2c使用这个数组访问方法而不是指针篡改?这似乎是f2c中的一个简单更改,并生成定义良好的代码,因此您可能会认为它已经是一个选项。
  • 除了跳过优化和希望程序行为良好(尽管依赖于未定义的行为),还有其他解决方案来解决这个问题吗?
  • 在c++编译器中有什么我可以做的吗?我使用微软C++ (2010)编译,作为一个托管c++项目。
EN

回答 2

Stack Overflow用户

发布于 2012-06-05 10:59:56

优化器只应确保没有明显的行为更改,因此它可以选择不执行递减操作,并使用递减索引访问数据(额外的偏移量可以是操作代码的一部分),因为函数使用指向数组的指针的副本。您没有告诉我们如何实际访问数组,以及优化器是否实际上引入了错误,因此我只能猜到这一点。

但是,正如slartibartfast已经说过的:这是一个未定义的行为,在检查*index >0之后,应该用int val = arr1[*index-1];代替减少

票数 5
EN

Stack Overflow用户

发布于 2012-06-05 10:47:53

将指针到数组移出指定的范围,然后访问它(尽管完整的表达式回到范围内)是未定义的行为AFAIK。然而,在几乎每一个实现上,这段代码都应该按照预期工作,所以问题是,您在看什么?也许在从arr1[]获取int的汇编程序指令中有一个隐含的预减量?仅仅因为您没有看到调试器中的减少,并不意味着它不存在。检查是否通过向其写入一个可区分的值来访问正确的元素。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10895769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档