Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Preprocessor to Generate Default Values

I am initialising a very large array with thousands of set values. I would like these values set at compile time rather than run time as they are fixed and will not change.

Is there a way of generating these values automatically, perhaps using the preprocessor? Currently I am generating these values using another small program then simply copying and pasting the values in respectively.

Here is what I am generating:

class MyClass
{
public:
    MyClass(int x, int y, int z) : X(x), Y(y), Z(z) {}

    int X, Y, Z;
};

std::vector<MyClass> my_vector{
    #include "my_vector_default_values.h"
};

my_vector_default_values.h

MyClass(0, 0, 1),
MyClass(0, 0, 2),
MyClass(0, 0, 3),
MyClass(0, 0, 4),
// etc... for thousands of lines
// ...

Edit:

The actual values I am generating are generated as follows (this is the C# program):

var sb = new StringBuilder();

var sizeX = 32;
var sizeY = 32;
var sizeZ = 32;

for (var x = 0; x < sizeX; x++)
{
    for (var y = 0; y < sizeY; y++)
    {
        for (var z = 0; z < sizeZ; z++)
        {
            sb.AppendLine($"MyClass({x}, {y}, {z}),");
        }
    }
}

var s = sb.ToString();
like image 785
rhughes Avatar asked Jul 05 '19 03:07

rhughes


People also ask

What is the default value of a #define in C?

After the pre-processing is over, all the undefined macros are initialized with default value 0.

What does ## mean in C preprocessor?

This is called token pasting or token concatenation. The ' ## ' preprocessing operator performs token pasting.

What is C++ preprocessor?

The preprocessor performs preliminary operations on C and C++ files before they are passed to the compiler. You can use the preprocessor to conditionally compile code, insert files, specify compile-time error messages, and apply machine-specific rules to sections of code.

Does C preprocessor remove comments?

Removing comments : It removes all the comments. A comment is written only for the humans to understand the code. So, it is obvious that they are of no use to a machine. So, preprocessor removes all of them as they are not required in the execution and won't be executed as well.


1 Answers

Here is some sample C++17 code, if you can make the class default-constructible:

#include <array>

const size_t gX = 32, gY = 32, gZ = 32;

class MyClass
{
public:
    int X, Y, Z;
};

constexpr std::array<MyClass, gX*gY*gZ> gen()
{
    std::array<MyClass, gX*gY*gZ> r{};
    size_t n = 0;

    for (int x = 0; x < gX; ++x)
        for (int y = 0; y < gY; ++y)
            for (int z = 0; z < gZ; ++z)
                r[n++] = { x, y, z };

    return r;
}

extern constexpr auto global = gen();

int main()
{
    return global[35].Z;
}

As you can see from the assembly output, the table was computed at compile-time.


Since C++17 std::array allows operator[] to be used in a constexpr manner. Prior to C++17, or if you want to retain the class's non-default-constructibility, you'd have to use variadic templates to generate a braced initializer for the array; this answer provides a code outline that you could modify to use your generation algorithm.

like image 63
M.M Avatar answered Sep 21 '22 07:09

M.M