Search code examples
c++ctemplatesgccequivalent

How can I convert this c++ template function to a C alternative?


I'm converting parts of a small C++ library to C (gcc). In doing so I'm wanting to convert the following template function to a macro (comments removed for readibility). CpuReadWriteFence() is another function that I've converted to a macro successfully.

template<typename T>
static inline T AtomicLoadAcquire(T const* addr)
{
    T v = *const_cast<T const volatile*>(addr);
    CpuReadWriteFence();
    return v;
}

Since there are no templates in C I'm either using functions or macros. GCC provides a convenient typeof extension. Perhaps I could do it with void*? if so how?

What I have so far is this:

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

However, that won't allow me to do this:

int x = AtomicStoreRelease(&bla);

How would I get around this ?


Solution

  • You almost got it right. The GCC "statements and declarations in expressions" extension does not have to return void.

    The last thing in the compound statement should be an expression followed by a semicolon; the value of this subexpression serves as the value of the entire construct. (If you use some other kind of statement last within the braces, the construct has type void, and thus effectively no value.)

    So you can define your macro as:

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

    Note the v; at the end of the macro. That's where the magic comes from.

    Also note that the first typeof takes *addr as an argument and there is no star after volatile typeof(addr). Those were some minor bugs unrelated to your main problem.