4

I am working with Visual Studio 2017 Community Edition. It allows me to use both size_t and std::size_t without the appropriate includes. It appears to work with most of the std library. I assume it is because parts of the library itself use it. For instance one example that I found led to this behave was with vector.

#include <vector>
#include <iostream>

int main()
{
    size_t a = 42;
    std::size_t b = 0;
    std::cout << a << b;
    std::cin.ignore();
}

Presumably this is because the size() function returns an std::size_t. Is this just a header dependency and I can avoid it with the proper include? That still doesn't explain why I can call it with the namespace scope.

(I'm not using using namespace std.)

This question implies that not all headers in the std library should have the definition.

Summer
  • 259
  • 1
  • 7
  • 18
  • 1
    The C++ standard does not define which header files specify which definitions. It only says that when including a header file certain definitions have to be available – UnholySheep Apr 15 '18 at 17:49
  • 1
    Hmm, I think the answers to [Which header should I include for `size_t`?](https://stackoverflow.com/questions/36594569/which-header-should-i-include-for-size-t) contain the information you are looking for? – UnholySheep Apr 15 '18 at 18:02
  • Also I can use `size_t` but not `std::size_t` on VS2017 without including any headers. (And as per the previously linked question it should be UB to do so) – UnholySheep Apr 15 '18 at 18:03
  • please create a [MCVE] – bolov Jun 05 '18 at 03:02
  • What exactly do you mean by "without including any headers"? You gave `vector` as an example; doesn't that mean you have `#include `? As @bolov suggested, we need a [mcve]. – Keith Thompson Jun 05 '18 at 03:12
  • 1
    @KeithThompson sorry old title - I updated the question because the behavior I described was inaccurate. – Summer Jun 05 '18 at 03:14

1 Answers1

3

Strictly speaking your code is illegal. The size_t type is required to be declared in the following headers:

<cstddef>
<cstdio>
<cstdlib>
<cstring>
<ctime>
<cwchar>

But also the standard allows standard headers to include other standard headers. So most likely the header <vector> in the standard library used by MSVC includes one of the headers above. This is allowed, but not mandated by the standard so this will work on your setup, but can fail to work on other standard library implementations, even on a future version of the same one you are using.

So in conclusion try to include all the headers required by the standard for all the definitions you are using.

IMHO this is a faulty behavior, but is the required price C++ pays for backward compatibility to the inclusion system that seemed a reasonable design many years ago. The limitations and drawbacks of this are well known today and so the committee is working on modules, which is a modern alternative to the current inclusion mechanism.


As to why you can use size_t without std:::

<cstddef> is required to declare std::size_t and may also optionally declare (or bring in the declaration of) size_t in the global scope.

<stddef.h> is a C backward compatible header and it declares size_t at the global scope.

So either <cstddef> declares size_t at a global level and is included by <vector> or <stddef.h> is included by <vector> - most likely indirectly via <cstddef>.

https://stackoverflow.com/a/283023/2805305

bolov
  • 72,283
  • 15
  • 145
  • 224