2

I have a constant lookup table which is keyed by fairly sparse "magic numbers"/ enumeration values, so standard {} positional initialization would at best be incredibly tedious.

I've tried initializing it in a separate source file, "constants.cpp"

#define SORT_ARRAY_SIZE 1024
size_t kSortArray[SORT_ARRAY_SIZE];

void InitializeSortArray()
{

    //  Only a subset of the reserved SORT_ARRAY_SIZE positions are used.
    //  Which ones are compile-time "magic numbers".
    for (int i = 0; i < SORT_ARRAY_SIZE; ++i)
    {
        switch (i)
        {
        case 57:  //  Magic number #1.
            kSortArray[i] = 0;
            break;
        case 213:  //  Magic number #2.
            kSortArray[i] = 1;
            break;
        }
    }
}

And then making it external in a header file, constants.h

#ifndef CONSTANTS_H
#define CONSTANTS_H

#define SORT_ARRAY_SIZE 1024
extern size_t kSortArray[SORT_ARRAY_SIZE];
#endif

It's then used in the main file binner.c e.g.

int main(int argc, char* argv[])
{
    kSortArray[0] = 3;  //  Compile-time error desirable.
    return 0;
}

All that compiles and works fine, except that the assignment in main doesn't cause a compile-time error because I haven't yet declared "kSortArray" as a constant anywhere. But when I try including a constant keyword in either of "constants.h / constants.cpp" I get errors. Is this approach doomed to failure?

I tried some other suggestions like putting it in a class and using the constructor function but my attempt threw all sorts of template errors.

Any help much appreciated.

4
  • 2
    Using a class (and then creating a static const object of that class) would be a viable way of doing it. Can you show us what you've tried, and exactly what kinds of errors you've been getting? Commented Jan 22, 2016 at 12:50
  • Just for your information, since the array is declared in the global scope all elements will be initialized to zero by default. Commented Jan 22, 2016 at 12:51
  • Most of the elements will be unused, it doesn't matter what they get initialized to - only the "magic-number" values need to have specific values. Thanks Joachim - didn't know I could edit. Commented Jan 22, 2016 at 12:51
  • 1
    @DLyons You do know you can edit your questions? Down below the tags there is a link for that. Commented Jan 22, 2016 at 12:52

1 Answer 1

1

I suggest doing it like this

//   in the header

//   include whatever header you're using to declare size_t

const size_t SORT_ARRAY_SIZE = 1028;
extern const size_t *kSortArray;

//  in your constants compilation unit


namespace
{
    static size_t the_array[SORT_ARRAY_SIZE];
}

const size_t *kSortArray = ::the_array;

Then change your InitializeSortArray() so it initialises ::the_array.

Sign up to request clarification or add additional context in comments.

2 Comments

That's neat Peter! It certainly compiles and it seems to give the expected behaviour (i need to test more carefully). Is there any point in using #pragma once as well?
Include guards in the header will suffice for dealing with multiple inclusion

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.