Post your C/C++ macro tricks

I learned of a neat macro trick today, maybe old hat to most of you but maybe not

"#" is a "stringify" operator, which you can use to sort of replicate reflection-ish features.

For instance say you wanted a utility function to serialize something to json, you can do something like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#define writeInt(x) _writeInt(#x,x)

writeInt(mass);

//and it will expand to:

_writeInt("mass",mass);


#define loadInt(x,json) x = _loadInt(#x,json)

//expands to:

mass = _loadInt("mass",json);



Saves us a ton of boilerplate, and prevents you from miss typing string literals.


Edited by Jack Mott on Reason: code
Honestly I'm a big fan of macros, sometimes I even unnecessarily overuse them.

I either use it to add some reflection or I substitute common code snippets to make it easier for me when coding.

There is one particular macro I used to do, but then found out it's unpractical and also quite useless for me since I've left OOP for now:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#define CLASS(p) class p\
{\
	inline virtual std::string _GetClassName_() { return #p; }

//which then could be used as
CLASS(TestClass)
    void DoStuff();
    //...
};

//due to missing brace in code, it broke some VS functionalities and highlighting (which breaks on everything now, excuse me for highlighting).
//I've got rid of this macro and added a factory (which is not related, see below), vector holding pair of string (class name) and class constructor.
//but tbh, I still use simplified version of CLASS macro for ex. as:
class BigDoor : Door
{
public:
    REGCLASS("BigDoor") // inline virtual std::string __GetClassName__() { return "BigDoor"; }
    //...
};
// and so on..


When it comes to macros, I do silly ones often, then there's common stuff like:
1
2
3
4
5
#define SCALL(x, c) if (x != nullptr) c

//or
#include <stdio.h>
#define ASSERT(p,q) if(!p) { fprintf(stderr, "ERROR: \"" ## q ## "\" IN " __FILE__ " AT LINE %d!\n", __LINE__); *(int*)0=0; } 


Which is pretty self-explanatory and maybe useless, I guess.

I'd like to see some interesting tricks, there's always a time to learn something new.

Edited by Dominik Madarász on Reason: added macro.
I like the SCALL! That could come in handy.

I just stumbled on another reflection-ish trick with enums, that I am really excited about because I spent hours trying to find a good way to get a ENUM tied to the strings it represents:

http://stackoverflow.com/question...convert-enum-names-to-string-in-c
Thanks, I'll look into that one. It's nice to have this topic, always stuff to learn.
I dislike macros that create multiple statements. Doing them for definitions or declarations is fine. But I'm strongly against mult-statement macros. Why? Because there is no easy way to debug them, meaning - you cannot step statement by statement and examing values in debugger.
Not too interesting, but funny:

1
#define private public
Horrowind
Not too interesting, but funny:

1
#define private public


That's not complete without

1
2
#define class struct
#define protected public
Here's a little trick to creating generic functions and types. Multiple include with the same file, and you just switch the VAR_TYPE and VAR_NAME between includes.
This is a bounded/sized array implementation that only requires 3 lines of code to create a new type.
1
2
3
#define VAR_TYPE float // the type you want.
#define VAR_NAME f32 // type name appended to the struct / function.
#include "bound_array.cpp"



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// "main.cpp"
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>

#define CONCAT_(a,b) a##b
#define CONCAT(a,b) CONCAT_(a,b)

#define VAR_TYPE float
#define VAR_NAME f32
#include "bound_array.cpp"

#define VAR_TYPE int64_t
#define VAR_NAME s64
#include "bound_array.cpp"

int main()
{
    Array_f32 eple = Array_f32_init(32);
    eple[31] = 91;
    printf("eple.size = %lu\neple[31] = %f\n", eple.size, eple[31]);
    
    
    Array_s64 pera = Array_s64_init(54);
    pera[24] = 3771;
    printf("pera.size = %lu\npera[24] = %li\n", pera.size, pera[24]);
    
    return 0;
}


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// "bound_array.cpp"
#ifndef VAR_TYPE
#error "VAR_TYPE is not defined."
#endif
#ifndef VAR_NAME
#error "VAR_NAME is not defined."
#endif

#define ARRAY_TYPE CONCAT(Array_, VAR_NAME)
struct ARRAY_TYPE{
    uint64_t size;
    VAR_TYPE *element;
    
    VAR_TYPE &operator [](uint64_t index)
    {
        assert(index < size);
        return element[index];
    }
};

static
ARRAY_TYPE CONCAT(ARRAY_TYPE, _init) (uint64_t size_in)
{
    ARRAY_TYPE result;
    result.element = (VAR_TYPE *)malloc(size_in * sizeof(VAR_TYPE));
    assert(result.element);
    result.size = size_in;
    return result;
}

#undef ARRAY_TYPE
#undef VAR_TYPE
#undef VAR_NAME
My favorite macro trick is for making something that looks like a resumable function call, sort of like a really light weight coroutine. So you can write code that says "ahh at this point I would like to return to the user some info, but then when they call me I want to resume right after the return point".


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
struct State{
    int _pc_;
    
    // other variables that need to carry their value
    // over multiple resumes of the function call.
};

#define DrYield(c,v) do{ state->_pc_ = c; return(v); resume_##c:; } while(false)
#define DrReturn(v) do{ state->_pc_ = -1; return(v); } while(false)
#define DrCase(c) case c: goto resume_##c

void
foo(State *s, void *new_memory, File_Data file){
    switch (s->_pc_){
        DrCase(1);
        // ...
        DrCase(5);
    }
    
    // ... code stuff ...
    for (begin();check();increment()){
        if (need_memory_from_user()){
            DrYield(1, NeedMemory);
            // do something with new_memory
        }
        if (need_file_from_user()){
            DrYield(2, NeedFile);
            // do something with file
        }
        // ... code stuff ...
    }
    // ... code stuff ...
    
    DrReturn(state->success);
}


I did a video trying it out here if you want to see it in detail without using goto. The goto version is required if your resumable function might want to use switches itself though.

The only issue I don't like is having to list all the cases and giving each yield point a unique integer. I haven't found away around that using the goto version though.

Edited by Allen Webster on Reason: Make parameters explicit
Mr4thDimention
My favorite macro trick is for making something that looks like a resumable function call, sort of like a really light weight coroutine. So you can write code that says "ahh at this point I would like to return to the user some info, but then when they call me I want to resume right after the return point".


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
struct State{
    int _pc_;
    
    // other variables that need to carry their value
    // over multiple resumes of the function call.
};

#define DrYield(c,v) do{ state->_pc_ = c; return(v); resume_##c:; } while(false)
#define DrReturn(v) do{ state->_pc_ = -1; return(v); } while(false)
#define DrCase(c) case c: goto resume_##c

void
foo(State *s, void *new_memory, File_Data file){
    switch (s->_pc_){
        DrCase(1);
        // ...
        DrCase(5);
    }
    
    // ... code stuff ...
    for (begin();check();increment()){
        if (need_memory_from_user()){
            DrYield(1, NeedMemory);
            // do something with new_memory
        }
        if (need_file_from_user()){
            DrYield(2, NeedFile);
            // do something with file
        }
        // ... code stuff ...
    }
    // ... code stuff ...
    
    DrReturn(state->success);
}


I did a video trying it out here if you want to see it in detail without using goto. The goto version is required if your resumable function might want to use switches itself though.

The only issue I don't like is having to list all the cases and giving each yield point a unique integer. I haven't found away around that using the goto version though.


if you don't mind using non-standard GCC extension you can use label as value: http://stackoverflow.com/q/1777990/731620

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
struct State{
    void* _pc_;
    //...
}
#define DrYield(v) do{ state->_pc_ = &&resume_## __LINE__; return(v); resume_##__LINE__:; } while(false)
#define DrReturn(v) do{ state->_pc_ = 0; return(v); } while(false)

void
foo(State *s, void *new_memory, File_Data file){
    if(s->_pc_) goto *s->_pc_;
    //...
}
Computed goto statements are a very nice thing. They allow to create lower-overhead interpreters than a regular switch statement: http://eli.thegreenplace.net/2012...oto-for-efficient-dispatch-tables
Original Android Dalvik interpreter used computed goto (and few other tricks) to get better performance: https://android.googlesource.com/...2415b48bdef63/vm/mterp/README.txt

Unfortunately no MSVC support, until we get clang fronted :(

Edited by Mārtiņš Možeiko on
I am skeptical that these computed gotos are necessary to get the "improved" performance. For example, in MSVC you would just place an __assume(0) in the default: case of a switch and it would no longer emit the bounds-checking code, right? Has anyone done a more thorough analysis as to whether these are interesting?

- Casey
I have used computed goto for gcc compiler before and it does creates better code.

Here's a micro-benchmark: https://gist.github.com/mmozeiko/...681dde202bd9bfe8fe185844858f04eaf
It's a tiny VM that performs "--x" operation billion times.

For gcc 5.3.0 it creates ~10% faster code for computed goto:
1
2
3
switch = 2132
goto   = 1913
improvement = 10%


Unfortunately gcc generates range check even with __builtin_unreachable in default case.

Edited by Mārtiņš Možeiko on
Here are some of my favourites:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Token to String
#define TO_STRING(x) #x

// Static Assertion
#define STATIC_ASSERT3(cond, msg) typedef char static_assertion_##msg[(!!(cond))*2-1]
#define STATIC_ASSERT2(cond, line) STATIC_ASSERT3(cond, static_assertion_at_line_##line)
#define STATIC_ASSERT1(cond, line) STATIC_ASSERT2(cond, line)
#define STATIC_ASSERT(cond)        STATIC_ASSERT1(cond, __LINE__)

// *_of "operators"
typedef ptrdiff_t isize;
// Signed sizeof is more useful
#define size_of(x) (isize)(sizeof(x))
// Prevents C++ arrays from being passed
#define count_of(x) ((size_of(x)/size_of(0[x])) / ((isize)(!(size_of(x) % size_of(0[x])))))
#define offset_of(Type, element) ((isize)&(((Type *)0)->element))
// C-Only
#define align_of(Type) offset_of(struct { char c; Type member; }, member)


// Swap
#define swap(Type, a, b) do { Type tmp = (a); (a) = (b); (b) = tmp; } while (0)


// Bit cast: Very similar to doing `*(T *)(&u)` but can be faster
#define BIT_CAST(dest, source) do { \
	STATIC_ASSERT(size_of(*(dest)) <= size_of(source)); \
	memcpy((dest), &(source), size_of(*dest)); \
} while (0)

// Cast - Easy to grep
#define cast(Type) (Type)



I have loads more in gb.h.

Edited by Ginger Bill on
cmuratori
I am skeptical that these computed gotos are necessary to get the "improved" performance. For example, in MSVC you would just place an __assume(0) in the default: case of a switch and it would no longer emit the bounds-checking code, right? Has anyone done a more thorough analysis as to whether these are interesting?

- Casey


It has to emit the bounds check because __pc__ can be anything (being passed in through pointer) and a switch has well defined behavior in all cases (a empty default being inserted if not present).

There may be hope if you make the default case be undefined behavior and let the optimizer run with that. This of course has the issue that you are relying on the optimizer's behavior for optimal code.

edit: and I should have looked up what __assume(0) does...

Edited by ratchetfreak on