鍍金池/ 問答/PHP  C  Linux/ C語言函數(shù)轉(zhuǎn)成宏的一個(gè)疑問

C語言函數(shù)轉(zhuǎn)成宏的一個(gè)疑問

舉例來說有如下代碼,我想將函數(shù)compare_and_swap轉(zhuǎn)為宏實(shí)現(xiàn),這樣做的好處是編譯的時(shí)候不用檢查傳入的參數(shù)類型.
我搜了下宏的話換行使用單斜線,為了避免括號(hào)吞噬問題使用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;
}


下面是我改寫之后的代碼,卻一直報(bào)錯(cuò):

#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 =就沒有報(bào)錯(cuò),只有告警了,這是為什么?
程序的邏輯以來compare_and_swap宏返回的結(jié)果,我今天有點(diǎn)暈,求各位大佬指教,平時(shí)寫一些宏都是#define max(a,b)這種級(jí)別的.

回答
編輯回答
涼薄

記住,宏發(fā)生在編譯前,所以你只要把你的宏的代碼完整地放到引用它的地方就能知道問題出在哪里了

2017年1月8日 11:02