I was hacking today at work, and I needed to define the CPU architecture of the machine at some point.
Then I typed “c++ os module” on google, hoping I’ll find an equivalent of the node:os
module in Node.Js.
I was stunned to find out that my lovely os.arch()
(or process.arch
) has no equivalent on C++.
A few queries later, I found it. My answer has a name: “pre-processor”!
✅ What you’ll be able to do at the end of this article?
Pre-processor happens before compilation, and it will examine the code and will resolve directives within the code. The most known is the include
directive:
Includes other source file into current source file at the line immediately after the directive.
Source: https://en.cppreference.com/w/cpp/preprocessor/include
A directive is a statement that starts with a #
followed by an instruction. The pre-processor will execute the instruction before compilation. Let’s take an example by defining a macro:
#define MAX_SIZE 30
if (size > MAX_SIZE) {
...
}
Define a macro with the “define” directiveAfter the pre-processor step, the code looks like this:
if (size > 30) {
...
}
For our use case, the pre-processor directive we need is “conditional inclusion”. It allows you to include or not a part of the code.
Let’s write an example where we want to warn the user conditionally.
// Display an error message if MAX\_SIZE is not defined
#ifndef MAX_SIZE
std::cerr << "MAX_SIZE is not defined" << std::endl;
#endif
“We seem far away from the CPU architecture definition, my boy!”.
Yeah, indeed! I’ll add my last ingredient to the recipe: the predefined macros!
As I said above, there is no built-in function to get the CPU architecture. But compilers bring pre-defined macros:
C and C++ compilers automatically define certain macros that can be used to check for compiler or operating system features. This is useful when writing portable software.
Pre-defined Compiler Macros / Wiki / Home!
There is a specific category that will help us: “architectures”:
Pre-defined Compiler Macros / Wiki / Architectures
❓Question: Is the fact that macros are defined by compilers the reason why we don’t have something exposed in the standard library? I’ll try to figure out this and answer it later!
Now we can imagine using these macros to define the CPU architecture. Let’s try it!
Then I’ll use the __arm__
, __aarch64__
& __x86_64__
macros to define an arch
variable of type std::string
:
// Define CPU architecture in C++ with pre-processor
#if defined(__arm__)
std::string arch = "arm";
#elif defined(__aarch64__)
std::string arch = "arm64";
#elif defined(__x86_64__)
std::string arch = "x64";
#else
std::string arch = "unknown";
#endif
I only handle a few cases here, but you can expand it as much as you want.
If we summarize a bit, we know:
If you want to read more about pre-processor and macros: