这条线想做什么

What is this line trying to do?

本文关键字:什么      更新时间:2023-10-16

我正在尝试编译一个三角++库(Triangle.h库上的c ++包装器),但我被困在了这一行:

else if (m->lastflip->prevflip == (struct flipstacker *) &insertvertex)

这显然会引发类型转换错误 (VC++12):

cannot convert from 'piyush::insertvertexresult (__thiscall piyush::* )(piyush::mesh *,piyush::behavior *,piyush::vertex,piyush::otri *,piyush::osub *,int,int)' to 'piyush::flipstacker *'

将函数指针强制转换为结构指针?这是一些我不知道的黑魔法

这是insertvertex函数:

enum insertvertexresult insertvertex(struct mesh *m, struct behavior *b,
                                     vertex newvertex, struct otri *searchtri,
                                     struct osub *splitseg,
                                     int segmentflaws, int triflaws)

insertvertexresult枚举:

/* Labels that signify the result of vertex insertion.  The result indicates */
/*   that the vertex was inserted with complete success, was inserted but    */
/*   encroaches upon a subsegment, was not inserted because it lies on a     */
/*   segment, or was not inserted because another vertex occupies the same   */
/*   location.                                                               */
enum insertvertexresult {SUCCESSFULVERTEX, ENCROACHINGVERTEX, VIOLATINGVERTEX,
                         DUPLICATEVERTEX};

flipstacker结构:

/* A stack of triangles flipped during the most recent vertex insertion.     */
/*   The stack is used to undo the vertex insertion if the vertex encroaches */
/*   upon a subsegment.                                                      */
struct flipstacker {
  triangle flippedtri;                       /* A recently flipped triangle. */
  struct flipstacker *prevflip;               /* Previous flip in the stack. */
};

为方便起见,完整的上下文(找到上述强制转换的unovertex函数):

/*****************************************************************************/
/*                                                                           */
/*  undovertex()   Undo the most recent vertex insertion.                    */
/*                                                                           */
/*  Walks through the list of transformations (flips and a vertex insertion) */
/*  in the reverse of the order in which they were done, and undoes them.    */
/*  The inserted vertex is removed from the triangulation and deallocated.   */
/*  Two triangles (possibly just one) are also deallocated.                  */
/*                                                                           */
/*****************************************************************************/
void undovertex(struct mesh *m, struct behavior *b)   
{
  struct otri fliptri;
  struct otri botleft, botright, topright;
  struct otri botlcasing, botrcasing, toprcasing;
  struct otri gluetri;
  struct osub botlsubseg, botrsubseg, toprsubseg;
  vertex botvertex, rightvertex;
  triangle ptr;                         /* Temporary variable used by sym(). */
  subseg sptr;                      /* Temporary variable used by tspivot(). */
  /* Walk through the list of transformations (flips and a vertex insertion) */
  /*   in the reverse of the order in which they were done, and undo them.   */
  while (m->lastflip != (struct flipstacker *) NULL) {
    /* Find a triangle involved in the last unreversed transformation. */
    decode(m->lastflip->flippedtri, fliptri);
    /* We are reversing one of three transformations:  a trisection of one */
    /*   triangle into three (by inserting a vertex in the triangle), a    */
    /*   bisection of two triangles into four (by inserting a vertex in an */
    /*   edge), or an edge flip.                                           */
    if (m->lastflip->prevflip == (struct flipstacker *) NULL) {
      /* Restore a triangle that was split into three triangles, */
      /*   so it is again one triangle.                          */
      dprev(fliptri, botleft);
      lnextself(botleft);
      onext(fliptri, botright);
      lprevself(botright);
      sym(botleft, botlcasing);
      sym(botright, botrcasing);
      dest(botleft, botvertex);
      setapex(fliptri, botvertex);
      lnextself(fliptri);
      bond(fliptri, botlcasing);
      tspivot(botleft, botlsubseg);
      tsbond(fliptri, botlsubseg);
      lnextself(fliptri);
      bond(fliptri, botrcasing);
      tspivot(botright, botrsubseg);
      tsbond(fliptri, botrsubseg);
      /* Delete the two spliced-out triangles. */
      triangledealloc(m, botleft.tri);
      triangledealloc(m, botright.tri);
    } else if (m->lastflip->prevflip == (struct flipstacker *) &insertvertex) {
      /* Restore two triangles that were split into four triangles, */
      /*   so they are again two triangles.                         */
      lprev(fliptri, gluetri);
      sym(gluetri, botright);
      lnextself(botright);
      sym(botright, botrcasing);
      dest(botright, rightvertex);
      setorg(fliptri, rightvertex);
      bond(gluetri, botrcasing);
      tspivot(botright, botrsubseg);
      tsbond(gluetri, botrsubseg);
      /* Delete the spliced-out triangle. */
      triangledealloc(m, botright.tri);
      sym(fliptri, gluetri);
      if (gluetri.tri != m->dummytri) {
        lnextself(gluetri);
        dnext(gluetri, topright);
        sym(topright, toprcasing);
        setorg(gluetri, rightvertex);
        bond(gluetri, toprcasing);
        tspivot(topright, toprsubseg);
        tsbond(gluetri, toprsubseg);
        /* Delete the spliced-out triangle. */
        triangledealloc(m, topright.tri);
      }
      /* This is the end of the list, sneakily encoded. */
      m->lastflip->prevflip = (struct flipstacker *) NULL;
    } else {
      /* Undo an edge flip. */
      unflip(m, b, &fliptri);
    }
    /* Go on and process the next transformation. */
    m->lastflip = m->lastflip->prevflip;
  }
}

我的问题是,这样的演员试图完成什么,为什么这甚至可能?

现在这个演员阵容确实没有任何意义。

但是在浏览了一下代码后,我发现:

if (m->checkquality) {
  poolrestart(&m->flipstackers);
  m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers);
  m->lastflip->flippedtri = encode(horiz);
  printf("Fatal Error: Contact piyushn");
  exit(1);
  /* 
  m->lastflip->prevflip = (struct flipstacker *) &insertvertex; 
  */
}

请注意,有同样奇怪的演员阵容,但这次是任务。

所以有两种可能性:

  • 要么在某个时间点insertvertex不是一个函数,而是一个实际上可以投射到(struct flipstacker *)的对象,

  • 或者作者使用 insertvertex 的地址作为魔术值,知道没有有效的 flipstacker 对象可以与 insertvertex 函数位于同一地址,并且作者的编译器不知何故从未抱怨过。

无论哪种方式,这都是一个糟糕的做法,而且由于现在魔术赋值被注释掉了,这种情况似乎本质上是死代码,我建议填写错误报告并在此期间简单地将其删除。