C++ 如何转换此c++;模板函数到C的替代?
我把一个小型C++库的部分转换成C(GCC)。在这样做的过程中,我希望将下面的模板函数转换为宏(为了可读性而删除注释)。CpuReadWriteFence()是我成功转换为宏的另一个函数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();
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; })