我正在尝试编译此软件包: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;
}
答案 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