举例来说有如下代码,我想将函数compare_and_swap转为宏实现,这样做的好处是编译的时候不用检查传入的参数类型.
我搜了下宏的话换行使用单斜线,为了避免括号吞噬问题使用do while(0);形式
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
static unsigned long count = 0;
int compare_and_swap(int *reg,int oldval,int incre)
{
register char result;
__asm__ volatile ("lock; cmpxchgl %3, %0; setz %1" : "=m"(*reg), "=q" (result) : "m" (*reg), "r" (oldval + incre), "a" (oldval) : "memory");
return result;
}
void *test_func(void *arg)
{
int i=0;
int ret;
for(i=0;i<2000;++i)
{
ret = 0;
while(0 == ret){
ret = compare_and_swap((int *)&count, count, 1);
}
}
return NULL;
}
int main(int argc, const char *argv[])
{
pthread_t id[10];
int i = 0;
for(i=0;i<10;++i){
pthread_create(&id[i],NULL,test_func,NULL);
}
for(i=0;i<10;++i){
pthread_join(id[i],NULL);
}
//10*2000=200000
printf("%u\n",count);
return 0;
}
下面是我改写之后的代码,却一直报错:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
static unsigned long count = 0;
#define compare_and_swap(reg,oldval,incre)\
do{ register char result;\
__asm__ volatile ("lock; cmpxchgl %3, %0; setz %1" : "=m"(*reg), "=q" (result) : "m" (*reg), "r" (oldval + incre), "a" (oldval) : "memory");\
return result;\
}while(0)
void *test_func(void *arg)
{
int i=0;
int ret;
for(i=0;i<2000;++i)
{
ret = 0;
while(0 == ret){
ret = compare_and_swap((int *)&count, count, 1);
}
}
return NULL;
}
int main(int argc, const char *argv[])
{
pthread_t id[10];
int i = 0;
for(i=0;i<10;++i){
pthread_create(&id[i],NULL,test_func,NULL);
}
for(i=0;i<10;++i){
pthread_join(id[i],NULL);
}
//10*2000=200000
printf("%u\n",count);
return 0;
}
提示mas.c: In function ‘test_func’:
mas.c:24: error: expected expression before ‘do’
在24行处将ret = compare_and_swap((int *)&count, count, 1);去掉ret =就没有报错,只有告警了,这是为什么?
程序的逻辑以来compare_and_swap宏返回的结果,我今天有点晕,求各位大佬指教,平时写一些宏都是#define max(a,b)这种级别的.
记住,宏发生在编译前,所以你只要把你的宏的代码完整地放到引用它的地方就能知道问题出在哪里了