语法错误:“do”前的期望表达式

时间:2021-01-29 22:43:30

I am trying to compile this software package: http://sourceforge.net/projects/snap-graph/?source=dlp

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

I hit a syntax error here:

我在这里犯了一个语法错误:

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

The relevant code section where the error appear is. In particular, line 214: queue[atomic_fetch_and_add (&k2, 1)] = w; Any ideas what might be the problem?

出现错误的相关代码部分。特别是,第214行:队列[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 个解决方案

#1


1  

The error you are bumping in appears only if the sources are compiled without OpenMP support.

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

Possiblities on how to patch the source to also comple in this situation were already provide by other answers.

在这种情况下,如何对源进行补丁的可能性已经由其他答案提供了。

Another approach to solve the OP's problem would be to enable support for OpenMP prior to compilation.

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

This can be done by passing the appropriate option to the configure script:

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

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

This should produce the following output:

这将产生以下输出:

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

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

...

Then compiling the sources using a simple

然后使用简单的方法编译源代码。

snap-0.4$ make

should work seamlessly.

应该无缝地工作。


Note

请注意

This would only work for compilers having #defineed:

这只适用于有#定义的编译器:

  • __GNUC__
  • __GNUC__

or/and

或/和

  • __INTEL_COMPILER
  • __INTEL_COMPILER

#2


2  

Just guessing on the basis of the comments to your question. Given its name, it seems that

只是根据你的问题的评论来猜测。考虑到它的名字,它似乎是。

atomic_fetch_and_add(&k2, 1)

is an atomic version of k2 += 1, i.e. an operation that is guaranteed not to be interrupted between the moment when k2 is read and the moment when its value incremented by one is stored back in k2. If this assumption is true, you could try replacing the line:

是k2 += 1的原子版本,也就是说,当k2被读取的时刻和它的值递增的时刻被存储在k2中时,保证不被中断的操作。如果这个假设是正确的,你可以试着换句话说:

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

with the following two lines:

有以下两行:

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

#3


1  

(Copying and expanding from comments.)

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

Given the context of the compilation error:

考虑到编译错误的上下文:

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

and the error message:

错误消息:

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

it's very likely that atomic_fetch_and_add is a function-like macro defined using the do { ... } while (0) idiom, as described in question 10.4 of the comp.lang.c FAQ.

atomic_fetch_and_add很可能是使用do{…while(0)成语,如问题10.4所描述的那样。c FAQ。

Such a macro is designed to be usable in a context that requires a statement, but cannot be used in a context that requires an expression.

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

Probably the developer used a system where atomic_fetch_and_add is defined so that it can be used in an expression context (it probably expands to an expression that yields the incremented value of k2).

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

Lorenzo Donati's answer suggests a possible workaround: putting the invocation of atomic_fetch_and_add on a line of its own.

洛伦佐·多纳蒂的回答暗示了一种可能的解决方法:将atomic_fetch_and_add的调用放在自己的一行上。

A less portable workaround might be to take advantage of a gcc-spoecific extension: statement expressions, described here. You could probably replace

一个不太方便的变通方法可能是利用gcc-spoecific扩展:这里描述的语句表达式。你可以替换

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

by

通过

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

I do not recommend this approach, but if you have a lot of occurrences of this problem it might be easier to apply semi-automatically.

我不推荐这种方法,但是如果您遇到了很多这样的问题,那么可以更容易地应用半自动化。

I'd also recommend contacting the developers of the project so they can fix this error.

我还建议联系项目的开发人员,这样他们就可以解决这个错误。

#1


1  

The error you are bumping in appears only if the sources are compiled without OpenMP support.

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

Possiblities on how to patch the source to also comple in this situation were already provide by other answers.

在这种情况下,如何对源进行补丁的可能性已经由其他答案提供了。

Another approach to solve the OP's problem would be to enable support for OpenMP prior to compilation.

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

This can be done by passing the appropriate option to the configure script:

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

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

This should produce the following output:

这将产生以下输出:

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

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

...

Then compiling the sources using a simple

然后使用简单的方法编译源代码。

snap-0.4$ make

should work seamlessly.

应该无缝地工作。


Note

请注意

This would only work for compilers having #defineed:

这只适用于有#定义的编译器:

  • __GNUC__
  • __GNUC__

or/and

或/和

  • __INTEL_COMPILER
  • __INTEL_COMPILER

#2


2  

Just guessing on the basis of the comments to your question. Given its name, it seems that

只是根据你的问题的评论来猜测。考虑到它的名字,它似乎是。

atomic_fetch_and_add(&k2, 1)

is an atomic version of k2 += 1, i.e. an operation that is guaranteed not to be interrupted between the moment when k2 is read and the moment when its value incremented by one is stored back in k2. If this assumption is true, you could try replacing the line:

是k2 += 1的原子版本,也就是说,当k2被读取的时刻和它的值递增的时刻被存储在k2中时,保证不被中断的操作。如果这个假设是正确的,你可以试着换句话说:

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

with the following two lines:

有以下两行:

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

#3


1  

(Copying and expanding from comments.)

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

Given the context of the compilation error:

考虑到编译错误的上下文:

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

and the error message:

错误消息:

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

it's very likely that atomic_fetch_and_add is a function-like macro defined using the do { ... } while (0) idiom, as described in question 10.4 of the comp.lang.c FAQ.

atomic_fetch_and_add很可能是使用do{…while(0)成语,如问题10.4所描述的那样。c FAQ。

Such a macro is designed to be usable in a context that requires a statement, but cannot be used in a context that requires an expression.

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

Probably the developer used a system where atomic_fetch_and_add is defined so that it can be used in an expression context (it probably expands to an expression that yields the incremented value of k2).

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

Lorenzo Donati's answer suggests a possible workaround: putting the invocation of atomic_fetch_and_add on a line of its own.

洛伦佐·多纳蒂的回答暗示了一种可能的解决方法:将atomic_fetch_and_add的调用放在自己的一行上。

A less portable workaround might be to take advantage of a gcc-spoecific extension: statement expressions, described here. You could probably replace

一个不太方便的变通方法可能是利用gcc-spoecific扩展:这里描述的语句表达式。你可以替换

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

by

通过

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

I do not recommend this approach, but if you have a lot of occurrences of this problem it might be easier to apply semi-automatically.

我不推荐这种方法,但是如果您遇到了很多这样的问题,那么可以更容易地应用半自动化。

I'd also recommend contacting the developers of the project so they can fix this error.

我还建议联系项目的开发人员,这样他们就可以解决这个错误。