Uploaded image for project: 'Rules Repository'
  1. Rules Repository
  2. RSPEC-5020

Facilities in <random> should be used instead of "srand", "rand" and "random_shuffle"

    XMLWordPrintable

    Details

    • Message:
      Hide
      Replace "rand" with the facilities in <random>
      Replace "random_shuffle" with "shuffle"
      Show
      Replace "rand" with the facilities in <random> Replace "random_shuffle" with "shuffle"
    • Default Severity:
      Blocker
    • Impact:
      High
    • Likelihood:
      High
    • Default Quality Profiles:
      Sonar way, MISRA C++ 2008 recommended
    • Covered Languages:
      C++
    • Irrelevant for Languages:
      ABAP, APEX, C#, C, Cobol, CSS, Flex, Go, HTML, Java, JavaScript, Kotlin, Objective-C, PHP, PL/I, PL/SQL, Python, RPG, Ruby, Rust, Scala, Solidity, Swift, T-SQL, TypeScript, VB.Net, VB6, XML
    • Remediation Function:
      Constant/Issue
    • Constant Cost:
      5min
    • Analysis Level:
      Syntactic Analysis
    • Analysis Scope:
      Main Sources, Test Sources

      Description

      The use of srand together with rand to seed the random number generator and then generate numbers usually produces low-quality randomness. Further, rand can only provide a number between 0 and RAND_MAX, and it is left to the caller to transform the result into what is actually required (E.G. a float between 0 and 1 for a random percentage, an int between 1 and 6 for a dice game, ...), and that transformation might introduce additional biases.

      C++11 introduced the <random> library, which contains several high quality random value generators as well as statistical distributions you can use to put the results in the form you need. Those mechanisms should be used instead of rand and srand.

      Additionally, std::random_shuffle, which is deprecated in C+14 and removed in C+17, uses rand and should be replaced by std::shuffle, which uses the random number generators provided by <random>.

      Noncompliant Code Example

      #include <stdlib.h>
      #include <algorithm>
      // ...
      
      void f() {
        srand(time(nullptr)); // Noncompliant
        vector<int> v;
        int size = rand() % 1000 + 1000; // Noncompliant, note that this way of coercing the result introduces extra bias
        for (auto i = 0; i < size; ++i) {
          v.push_back(i);
        }
        random_shuffle(v.begin(), v.end()); // Noncompliant
        for (auto i : v) { cout << i << " "; }
      }
      

      Compliant Solution

      #include <algorithm>
      #include <random>
      // ...
      
      void f() {
        random_device rd;  // Will be used to obtain a seed for the random number engine
        mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
        uniform_int_distribution<> dis(1000, 1999); // Same distribution as before, but explicit and without bias
        vector<int> v;
        for (auto i = 0; i < dis(gen); ++i) {
          v.push_back(i);
        }
        shuffle(v.begin(), v.end(), gen);
        for (auto i : v) { cout << i << " "; }
      }
      

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned Unassigned
              Reporter:
              loic.joly Loïc Joly
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated: