mardi 26 juillet 2016

Replacing magic ID numbers with random IDs generated at compile-time

My app contains numerous IDs. I want to eventually make the code viewable by others, but not make it easy for runtime reverse engineers to look for easily known IDs. Also, during development it is helpful to have constant IDs in the log files for easier debugging. But at runtime I would like to make these IDs random by generating them during the Release compile. Suggested code using the <random> lib can be seen in GetRandomId1() below. constexpr makes their use in the code possible like in switch statements. However, I am having trouble using constexpr in my proposed function because <random> is not constexpr compatible. Is there another way to generate random numbers at compile time? Or is generating random numbers at compile time to be used as constants at runtime considered against the concept of constexpr?

#include <iostream>
#include <random>

// this is the code I would like to use to generate a random number at compile time
/*constexpr */int GetRandomId1()
{
  std::random_device rd; // non-deterministic seed
  std::mt19937 gen( rd() ); // with constexpr uncommented: 
    // error C3250: 'rd': declaration is not allowed in 'constexpr' function body
    // error C3249: illegal statement or sub-expression for 'constexpr' function
    // error C3250: 'gen': declaration is not allowed in 'constexpr' function body

  std::uniform_int_distribution<> distri( 1000, 9999 ); // with constexpr uncommented: 
    // error C3250: 'distri': declaration is not allowed in 'constexpr' function bod
    // error C3249: illegal statement or sub-expression for 'constexpr' function
    // error C2134: 'std::uniform_int<_Ty>::operator ()': call does not result in a constant expression

  return distri( gen );
}

// this code is what works so far
constexpr int GetRandomId2()
{
  return 22; // how to make somewhat random?
}

constexpr int AAA = 10;
//constexpr int AAA = GetRandonId1(); // error: is not constexpr function
constexpr int BBB = GetRandomId2(); // ok

void Func1( long ab )
{
  switch( ab )
  {
    case AAA:
      std::cout << AAA << std::endl;
      break;

    case BBB:
      std::cout << BBB << std::endl;
      break;
  }
}

int main()
{
  Func1( 22 ); // ok: prints 22

  return 0;
}

I am looking for a straight forward, maintainable solution like the one I proposed and unlike the heavy use of templates as proposed in How can I generate dense unique type IDs at compile time?. Also in this posting @jmihalicza points to the Random number generator for C++ template metaprograms research paper. This paper describes compile-time random number generation using template metaprogramming which is a complicated attempt that accomplishes a task for which IMO constexpr was (dare I say, or should have been?) designed.

Because of app architectural reasons I don’t have to worry about ID collisions so that is not a concern. The app code would make sure there would be no duplicates returned.




Aucun commentaire:

Enregistrer un commentaire