Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Initializer lists

Use case

Define known suspicious API patterns concisely.

Explanation

Initializer lists let us pass {a, b, c} syntax to functions. They do not allocate heap memory (unlike e.g. std::vector). Use them for read-only literal data.

Code

#include <initializer_list>
#include <iostream>
#include <string>
#include <vector>

struct ImportPattern {
  std::string dylib;
  std::vector<std::string> functions;

  ImportPattern(std::string d, std::initializer_list<std::string> funcs)
      : dylib(std::move(d)), functions(funcs) {}
};

void checkSuspiciousImports(std::initializer_list<ImportPattern> patterns) {
  std::cout << "Checking " << patterns.size() << " suspicious patterns:\n";
  for (const auto &p : patterns) {
    std::cout << "  " << p.dylib << ": ";
    for (const auto &f : p.functions) {
      std::cout << f << " ";
    }
    std::cout << "\n";
  }
}

int main() {
  // Outer: std::initializer_list<ImportPattern>
  // Middle: constructor call via braces
  // Inner: std::initializer_list<std::string>
  checkSuspiciousImports({{"libSystem.B.dylib", {"ptrace", "sysctl"}}});
  return 0;
}

View on GitHub.

Output

$ ./src/c++11/build/initializer-lists
Checking 1 suspicious patterns:
  libSystem.B.dylib: ptrace sysctl