语法错误:'do'之前的预期表达式

时间:2013-09-17 15:31:53

标签: c gcc syntax-error

我正在尝试编译此软件包:http://sourceforge.net/projects/snap-graph/?source=dlp

我在这里遇到语法错误:

gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I..  -I../include   -O3 -fomit-frame-pointer -malign-double -fstrict-aliasing -ffast-math -MT drive_seed_community_detection.o -MD -MP -MF .deps/drive_seed_community_detection.Tpo -c -o drive_seed_community_detection.o drive_seed_community_detection.c
drive_seed_community_detection.c: In function ‘identify_comm’:
drive_seed_community_detection.c:214:14: error: expected expression before ‘do’
make[2]: *** [drive_seed_community_detection.o] Fehler 1
make[2]: Leaving directory `/amd.home/home/s/workspace/snap-0.4/test'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/amd.home/home/s/workspace/snap-0.4'
make: *** [all] Error 2

出现错误的相关代码部分。特别是,第214行:queue[atomic_fetch_and_add (&k2, 1)] = w;任何想法可能是什么问题?

  /* Find and label the connected components. */
  ncomm = 0;
  for (attr_id_t kseed = 0; kseed < num_seeds; ++kseed) {
    attr_id_t k1, k2;
    const attr_id_t seedv = seeds[kseed];
    if (membership[seedv] != -2) continue;
    queue[0] = seedv;
    membership[seedv] = seedv;
    comm_root[ncomm] = seedv;

    k1 = 0;
    k2 = 1;
    do {
      const attr_id_t qkend = k2;
      attr_id_t cv = 0;
      OMP("omp parallel for reduction(+:cv)")
      for (attr_id_t k1i = k1; k1i < qkend; ++k1i) {
        const attr_id_t v = queue[k1i];
        const attr_id_t deg = xoff[v+1] - xoff[v];
        cv += deg;
        if (deg > comm_maxdeg[ncomm]) comm_maxdeg[ncomm] = deg;
        for (attr_id_t k = xoff[v]; k < xoff[v+1]; ++k) {
          const attr_id_t w = xadj[k];
          attr_id_t memb;
          if (membership[w] < -1) {
            atomic_val_compare_and_swap (memb, &membership[w], -2, seedv);
            if (memb < -1) {
              //if (membership[w] < -1) {
              //membership[w] = seedv;
              //int loc;
              //OMP("omp atomic") loc = k2++;
              queue[atomic_fetch_and_add (&k2, 1)] = w;
            }
          }
        }
      }
      k1 = qkend;
      comm_vol[ncomm] = cv;
    } while (k1 != k2);
    comm_size[ncomm] = k2;
    ++ncomm;
  }

3 个答案:

答案 0 :(得分:2)

根据对您问题的评论进行猜测。鉴于其名称,似乎

atomic_fetch_and_add(&k2, 1)

k2 += 1的原子版本,即保证在读取k2的时刻与其值增加1的时刻之间不会被中断的操作被存储回k2。 1}}。如果这个假设成立,你可以尝试替换这一行:

queue[atomic_fetch_and_add (&k2, 1)] = w;

有以下两行:

atomic_fetch_and_add (&k2, 1);
queue[k2] = w;

答案 1 :(得分:1)

(从评论中复制和扩展。)

鉴于编译错误的上下文:

queue[atomic_fetch_and_add (&k2, 1)] = w;

和错误消息:

drive_seed_community_detection.c:214:14: error: expected expression before ‘do’

atomic_fetch_and_add很可能是使用do { ... } while (0)惯用法定义的类似函数的宏,如comp.lang.c FAQ的问题10.4所述。

这样的宏被设计为在需要语句的上下文中可用,但不能在需要表达式的上下文中使用。

开发人员可能使用了一个系统,其中定义了atomic_fetch_and_add,以便它可以在表达式上下文中使用(它可能扩展为一个表达式,产生递增的值k2)。

Lorenzo Donati's answer建议了一种可行的解决方法:将atomic_fetch_and_add的调用放在自己的一行上。

不太便携的解决方法可能是利用gcc-spoecific扩展:语句表达式described here。你可以替换

queue[atomic_fetch_and_add (&k2, 1)] = w;

通过

queue[({atomic_fetch_and_add (&k2, 1); k2;})] = w;

我不建议采用这种方法,但如果您遇到此问题很多,则可能更容易半自动应用。

我还建议您联系项目的开发人员,以便他们可以解决此错误。

答案 2 :(得分:1)

只有在没有OpenMP支持的情况下编译源时,才会出现错误。

其他答案已经提供了关于如何修补源以在这种情况下完善的可能性。

解决OP问题的另一种方法是在编译之前启用对OpenMP的支持。

这可以通过将适当的选项传递给configure脚本来完成:

snap-0.4$ make clean    
snap-0.4$ ./configure --enable-openmp

这应该产生以下输出:

snap successfully configured! Please verify that
this configuration matches with your expectations.

   User Option                         Value          
------------------------------------------------------
   OpenMP support                      yes
   Enable debug                        no

...

然后使用简单的

编译源代码
snap-0.4$ make

应该无缝地工作。


注意

这仅适用于#define ed:

的编译器
  • __GNUC__

或/和

  • __INTEL_COMPILER