Counting the number of primes in C and C++11 I found this old piece of code that I wrote while I was learning C a while back:

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;math.h&gt;


int main(int argc, char *argv[]) {
    if (argc &lt; 2) {
        fprintf(stderr, "Usage: %s &lt;N&gt;\n", argv[0]);
        return 1;
    }

    size_t limit = strtoul(argv[1], (char **) NULL, 10);
    size_t i, j, res = 0;
    size_t isqrt = (size_t) sqrt(limit);
    char* numbers = calloc(limit, 1);

    for (i = 2; i &lt;= isqrt; i++) {
        if (numbers[i]) continue;
        for (j = i*i; j &lt; limit; j += i) numbers[j] = 1;
    }

    for (i = 2; i &lt; limit; i++) {
        if (!numbers[i]) ++res;
    }
    printf("%lu\n", res);
    free(numbers);
    return 0;
}


It's a sieve of Erathosthenes. Since now I started learning C++, I decided to rewrite it in C++11:

#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;vector&gt;
#include &lt;string&gt;
#include &lt;algorithm&gt;
#include &lt;math.h&gt;


int main(int argc, char *argv[]) {
    if (argc &lt; 2) {
        std::cerr &lt;&lt; "Usage: " &lt;&lt; argv[0] &lt;&lt; " &lt;N&gt;" &lt;&lt; std::endl;
        return 1;
    }

    size_t limit = std::stoul(argv[1]);
    size_t i, j, res = 0;
    size_t isqrt = size_t (sqrt(limit));
    std::unique_ptr&lt;std::vector&lt;bool&gt; &gt; sieve(new std::vector&lt;bool&gt;(limit));

    for (i = 2; i &lt;= isqrt; ++i) {
        if (sieve-&gt;at(i)) continue;
        for (j = i*i; j &lt; limit; j += i) sieve-&gt;at(j) = 1;
    }

    for_each(sieve-&gt;cbegin() + 2, sieve-&gt;cend(), [&amp;res](bool i) { res += !i; });
    std::cout &lt;&lt; res &lt;&lt; std::endl;
    return 0;
}


Is this the most idiomatic way to code in C++? I also tried to replace the first for loop with a for_each and a functor that accepts sieve, but in the end I decided it wasn't worth it and left it like that.

In both versions I am allocating on the heap because the sieve array/vector gets too big for the stack.

Interestingly, the C++ version is faster! I thought they were pretty much identical, but instead the C++ version wins by a large margin:

$ gcc --std=c99 -O3 erat.c -lm -o erat
$ time ./erat 1000000000
50847534
./erat 1000000000  11.50s user 0.41s system 99% cpu 11.927 total
$ g++ --std=c++14 -O2 erat.cpp -o erat2
$ time ./erat2 1000000000
50847534
./erat2 1000000000  8.52s user 0.02s system 99% cpu 8.554 total


Feedback on the C version is also welcomed!
Idiomatic C++ Review
#include &lt;math.h&gt;

C++ has its own version of math header.
#include &lt;cmath&gt;

Difference is all the functions are placed in the std namespace.
Prefer not to use std::endl.
        std::cerr &lt;&lt; &quot;Usage: &quot; &lt;&lt; argv[0] &lt;&lt; &quot; &lt;N&gt;&quot; &lt;&lt; std::endl;

Forcing a flush is not normally what you want to do. The streams will automatically flush when required and doing it manually will only make the code less efficient.
Prefer to put one variable per line. Also for loop counters can be declared inside the for statement (see below).
    size_t i, j, res = 0;

Don't dynamical allocate when a local variable will do:
    std::unique_ptr&lt;std::vector&lt;bool&gt; &gt; sieve(new std::vector&lt;bool&gt;(limit));

    // Should be
    std::vector&lt;bool&gt; sieve(limit);

Also std::vector&lt;bool&gt; is special. It is optimized for space not speed. It also has some other quirks that make it undesirable, so prefer std::vector&lt;char&gt; unless you really really need to save space. BUT because of the space saving you can get better caching which may improve time. In this case presumably because of the size of the vector keeping it as bool makes it much more efficient.
see: Comparing std::vector to std::vector
Declare loop variables inside the for:
    for (i = 2; i &lt;= isqrt; ++i) {

    // Usually written like this:
    for(int i = 2; i &lt;= isqrt; ++i) {

The at() method is a checked access to the member. It validates your index is in range (you don't do this in the C code).
        if (sieve-&gt;at(i)) continue;

Unless you are using unvalidated user input there is little need to use the at() method, prefer to use operator[].
In C++14 the functions std::begin() and std::end() were introduced to get the iterators for containers. You should prefer to use these as they work with arrays as well as the standard containers.
    for_each(sieve-&gt;cbegin() + 2, sieve-&gt;cend(), [&amp;res](bool i) { res += !i; });


    // Can be written as:
    auto begin = std::begin(sieve);
    std::advance(begin, 2);
    for_each(begin, std::end(sieve), [&amp;res](bool i) { res += !i; });

Don't bother with a return at the end of main.
    return 0;