Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ "size_t" doesn't need "cstddef" header?

Tags:

c++

I'm learning C++ with the book C++ Primer, and it says that "size_t" is defined in "cstddef" header, but in this exercise:

#include <iostream>

using namespace std;

int main()
{
    int ar[10];

    for (size_t x = 0; x < 10; ++x)
        ar[x] = x;

    for (auto a : ar)
        cout << ar[a] << " ";

    cout << endl;

    return 0;
}

That doesn't have included the header, Visual Studio 2017 (and c++ shell) compiles the program without error.

like image 662
John Midnight Avatar asked Jan 12 '18 21:01

John Midnight


1 Answers

size_t is really a grey area. std::size_t is the result type of sizeof, but sizeof is a built-in operator you can use without any #include at all. Consider this complete little program:

// no includes, no using namespace std

int main()
{
    auto x = sizeof(int); // x is std::size_t
}

On top of that, Visual C++ has always behaved a bit strangely here. Even with settings like /permissive- /std:c++latest in the newest version of the compiler, it still allows the following illegal code:

// no includes, no using namespace std

int main()
{
    size_t i  = 0;
}

In fact, it would even allow this:

// no includes, no using namespace std

int main()
{
    int ar[10];

    for (size_t x = 0; x < 10; ++x)
        ar[x] = x;

    for (auto a : ar)
        ;

    return 0;
}

Nevertheless, what others said about the indirect inclusion of headers is correct. To be precise, the C++ standard says the following about standard-library headers at §20.5.5.2:

A C++ header may include other C++ headers.

Which means that Visual C++ behaves correctly in your case anyway. Once you include <iostream>, the implementation is free to indirectly include one of the six standard C++ headers that define std::size_t, and your using namespace std; (which is evil) does the rest.

The C++ standard even guarantees some of such indirect inclusions, but this isn't one of them, so in order to make your code compatible with other compilers, you are strongly encouraged to include <cstddef> or one of the others that guarantee std::size_t.

like image 52
Christian Hackl Avatar answered Oct 03 '22 19:10

Christian Hackl