-1

I'm making a C++ application that implements a Symbol class (similar to Atom in XLib or :symbols in ruby), which essentially maps a string to a unique-per-string integer value from a lookup table.

This means that initializing a Symbol is the only part of using one that takes any significant amount of time, searching through the lookup table each time one is created.

Usually that's just a necessary evil, but it becomes a pain when doing this:

void someRepeatedlyCalledFunction () {
    doThingWithSymbol(Symbol("HardCodedSymbolString"));
}

This means every time I call this function, the entire symbol lookup happens again.

Of course, this can be avoided via:

Symbol _HardCodedSymbolString;

void someRepeatedlyCalledFunction () {
    if (!_HardCodedSymbolString.isSet())
        _HardCodedSymbolString = Symbol("HardCodedSymbolString");

    doThingWithSymbol(_HardCodedSymbolString);
}

But this is an unattractive thing to have to do often, so ideally it could be hidden behind a macro - _SYMBOL(name) or something like that. The problem with this is that, because this macro would be called from within a function, there's no way of defining the global variable for that symbol.

Alternatively, it'd be even better if hardcoded symbol values were added to the list at compile-time, so the proper symbol values are put in like constants - but I see no way of doing this without writing some sort of custom preprocessor step.

Is there a way to implement these solutions, or perhaps a better solution?

Ethan McTague
  • 2,236
  • 3
  • 21
  • 53
  • "searching through the lookup table each time one is created." Why would you do that instead of incrementing one integer, the last-created ID? – n. m. could be an AI May 07 '19 at 03:27
  • @n.m. When the same string value is passed a second time, it has the exact same integer representation. – Ethan McTague May 07 '19 at 03:28
  • 4
    Totally unrelated to your problem, but symbols beginning with an underscore and followed by an upper-case letter (or symbols beginning with an underscore in the global scope) are *reserved*, you should not create such symbols in your own code. See [What are the rules about using an underscore in a C++ identifier?](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) for more information. – Some programmer dude May 07 '19 at 03:30
  • Sorry I misunderstiood the question at first. Searching for a string in a look up table is an O(1) operation, why are you worried about it? Alternatively why not just say `static ID = Symbol("HardcodedSymbol")`? – n. m. could be an AI May 07 '19 at 03:35
  • @n.m. This is for a game engine (i.e. I'm fairly concerned about performance) and don't want to be iterating over a large array of strings repeatedly when I don't need to be. – Ethan McTague May 07 '19 at 03:36
  • 2
    If you want to *map* one value to another, perhaps e.g. `std::unordered_map`? – Some programmer dude May 07 '19 at 03:40
  • 2
    Let's try again. *It's an O(1) operation*. You don't need to iterate through a large array. – n. m. could be an AI May 07 '19 at 03:41
  • @n.m. And how would locating a particular value in an array take constant time, exactly? – Ethan McTague May 07 '19 at 03:43
  • 2
    Ever heard about hash tables? See `std::unordered_map`. – n. m. could be an AI May 07 '19 at 03:44
  • @n.m. ...that's not what I said I was using, though. – Ethan McTague May 07 '19 at 03:46
  • 2
    *...that's not what I said I was using, though.* – that's what you \*should\* be using. – Swordfish May 07 '19 at 03:52
  • Create static `Symbol` instances for the hardwires. – user207421 May 07 '19 at 08:39

1 Answers1

-3

You could make the variable static?

void someRepeatedlyCalledFunction () {
    static Symbol _HardCodedSymbolString;
    if (!_HardCodedSymbolString.isSet())
        _HardCodedSymbolString = Symbol("HardCodedSymbolString");

    doThingWithSymbol(_HardCodedSymbolString);
}

Alternatively, it'd be even better if hardcoded symbol values were added to the list at compile-time, so the proper symbol values are put in like constants - but I see no way of doing this without writing some sort of custom preprocessor step.

Should be easy enough to write a quick code generator (in whatever language you prefer)

robthebloke
  • 9,331
  • 9
  • 12