Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何转换此c++;模板函数到C的替代?_C++_C_Templates_Gcc_Equivalent - Fatal编程技术网

C++ 如何转换此c++;模板函数到C的替代?

C++ 如何转换此c++;模板函数到C的替代?,c++,c,templates,gcc,equivalent,C++,C,Templates,Gcc,Equivalent,我把一个小型C++库的部分转换成C(GCC)。在这样做的过程中,我希望将下面的模板函数转换为宏(为了可读性而删除注释)。CpuReadWriteFence()是我成功转换为宏的另一个函数 template<typename T> static inline T AtomicLoadAcquire(T const* addr) { T v = *const_cast<T const volatile*>(addr); CpuReadWriteFence();

我把一个小型C++库的部分转换成C(GCC)。在这样做的过程中,我希望将下面的模板函数转换为宏(为了可读性而删除注释)。CpuReadWriteFence()是我成功转换为宏的另一个函数

template<typename T>
static inline T AtomicLoadAcquire(T const* addr)
{
    T v = *const_cast<T const volatile*>(addr);
    CpuReadWriteFence();
    return v;
}
但是,这不允许我这样做:

int x = AtomicStoreRelease(&bla);

如何解决这个问题?

宏不能返回值。试试这个:

#define AtomicLoadAcquire(addr, ref)                                       \
  ({ typeof (addr) v = *(volatile typeof (addr) *)(addr); CpuReadWriteFence(); ref = v; })

int x;
AtomicStoreRelease(&bla, x); // Instead of int x = AtomicStoreRelease(&bla);

能否将返回值添加为宏参数?诸如此类:

#define AtomicLoadAcquire(addr, ret)                                       \
    ( typeof (addr) v = *(volatile typeof (addr) *)(addr); CpuReadWriteFence(); )
这很难看,但这会帮你:

AtomicLoadAcquire(someaddr, x);
翻译成:

/* assuming someaddr is int* */
int x = *(volatile int *)(someaddr); CpuReadWriteFence(); 
/* now you have x defined */.
这正是你想要的


另一个选项(正如miaout17所提到的)是在调用宏之前声明
x
,然后在开始时删除“
typeof(addr)
”,这样会更安全,IMHO。

在宏中传递类型可能是最好的方法:

static inline const volatile void* AtomicLoadAcquire_f(void const* addr)
{
    const volatile void* v = (void const volatile*)addr;
    CpuReadWriteFence();
    return v;
}
#define AtomicLoadAcquire(type, pointer) \
 (*((const volatile type*)AtomicLoadAcquire_f(pointer)))

int x = AtomicLoadAcquire(int, &bla);

你几乎把它做好了。GCC扩展不必返回void

复合语句中的最后一件事应该是后跟分号的表达式;此子表达式的值用作整个构造的值。(如果在大括号中使用其他类型的last语句,则构造的类型为void,因此实际上没有值。)

因此,您可以将宏定义为:

#define AtomicLoadAcquire(addr)                                       \
({ typeof (*addr) v = *(volatile typeof (addr) )(addr); CpuReadWriteFence(); v; })
注意
v。这就是魔法的来源


还要注意的是,第一个
typeof
*addr
作为参数,并且
volatile typeof(addr)
之后没有星号。这些是与你的主要问题无关的一些小错误。

我想知道,为什么你从C++转换成C?另一方面,如果编译器支持C1x功能,则可以使用关键字。无C1x。我将把这个代码链接到C中更大的代码中。我真的不想把C++代码拉进去。现在C++中有几个位,如果已经使用了GCC扩展,那么不妨使用其他的GCC扩展!Matt H已经在使用({})扩展,只是没有完全扩展。
#define AtomicLoadAcquire(addr)                                       \
({ typeof (*addr) v = *(volatile typeof (addr) )(addr); CpuReadWriteFence(); v; })