C语言函数转成宏的一个疑问

举例来说有如下代码,我想将函数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)这种级别的.

阅读 4.2k
1 个回答

记住,宏发生在编译前,所以你只要把你的宏的代码完整地放到引用它的地方就能知道问题出在哪里了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题