Use of macros in unreal

So I’ve been studying C++ for the past year which means I am definitely not an expert. However, I was curious as to why the engine uses macros when everything I have ever read says macros shouldn’t be used and are a thing of the past. I was curious then to what end does UE4 use macros and not another method? Are there still good uses for them? Thanks for any insight.

My thought on the subject, especially for blueprint users, is that a macro is good for a “one shot” to keep the main code small / clean. If I’m not mistaken, the blueprint graph of “Collapse Nodes” is just visual, and doesn’t do any code changes. However, if you’re using that code in multiple places though, you will want to use a function.

I would prefer an expert either confirm or correct my understanding of this though, as I am by no means a C++ expert, and my code skills are very, very old.

Ya, I would prefer that as well. I’m trying to learn about UE4 as I want to start programming in it. Thank you for your insight though. Much appreciated.

Macros have their place, just as goto statements do. It’s a good rule of thumb to minimize macros because they are hard to debug for example, but they can do things that templates and such cannot.

As to savior, using macros where a function would do is generally a bad idea. Just as using goto when a simple control statement like if would do is a bad idea.

It would be better to hear an official response from Epic, but yeah. Epic uses macros, along with templates, the build tool, and so forth, to hide necessary chunks from people who shouldn’t be touching them. Macros are difficult to debug, but it’s all things that you shouldn’t need to debug in a project. If it doesn’t work, then it’s Epic’s problem to fix on the engine side.

Of course, they give you source access too, so you are free to fork Epic’s side to suit your needs. They’ll hide things from typical users, though.

Anybody who says “macros shouldn’t be used” is not very good with C++. It is a good warning for a newbie, though, because they can be abused easily and can turn your code into mess. However, work with C# for few weeks and you’ll crave for macros to shorten all those pesky property getter/setter functions.

Macros allows you to substitute and insert ANY text ANYWHERE in the file. They ignore language syntax and function boundaries completely.
Macros are a good way to reduce large number of repeating text to few lines, or insert code in the middle of the file, however, there’s no type checking performed, and if you hit type error in the middle of macro, it will be hard to debug.

For example (print enum value as string using switch/case):



#include <iostream>
#include <string>

enum Errors {ErrorA=0, ErrorB, ErrorC};

std::ostream& operator<<(std::ostream& out, const Errors value){
    const char* s = 0;
#define PROCESS_VAL(p) case(p): s = #p; break;
    switch(value){
        PROCESS_VAL(ErrorA);     
        PROCESS_VAL(ErrorB);     
        PROCESS_VAL(ErrorC);
    }
#undef PROCESS_VAL

    return out << s;
}

int main(int argc, char** argv){
    std::cout << ErrorA << std::endl << ErrorB << std::endl << ErrorC << std::endl;
    return 0;   
}


Example of macro related problems:



#include <iostream>

#define MUL(a, b) a * b

int main(){
	int a = MUL(1 + 2, 2 + 3); // prints 8 instead of 15, because 1 + 2 * 2 + 3 = 1 + 4 + 3 = 8
	std::cout << a;
}




#include <iostream>

void test(){
	std::cout << "test" << std::endl;
}

void test2(){
	std::cout << "test2" << std::endl;
}

#define test test2

int main(){
	test(); //prints "test2"
}


In case of unreal engine, they use macros in order to insert additional technical data for Garbage collection-related bookkeeping into classes.

Qt 4 framework does something similar with their Q_OBJECT macro.

It is absolutely valid way to use macros in this situation.

1 Like

Wow thank you for your in depth and thorough response! I will definitely keep this in mind when someone says never use macros.