Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What to do with size_t vs. std::size_t?

Tags:

c++

size-t

Having just read:

Does "std::size_t" make sense in C++?

I realize using ::size_t is not standards-compliant (although supported by my compiler) when you #include <cstddef>. I want to comply with the standard, but I do not want to prepend std:: to all of my size_t's. So, what is the more customary/popular way to handle this:

  • write using std::size_t;?
  • include <stddef.h>?
  • just rely on compiler support?
  • something else?
like image 258
einpoklum Avatar asked Mar 14 '17 21:03

einpoklum


1 Answers

You should specify it with the using directive.

using std::size_t;

Add it either to the global scope of each compilation unit, or to the local scopes if it would cause interference at the global scope.

stddef.h also works, as you noted, and honestly that method is not "worse" than this one. However, stddef.h is a backwards compatibility header, and it might be best to avoid relying on it in new code.

I prefer the using directive because it does not pollute the global namespace anywhere you don't need to, and does not rely on arbitrary compiler support of nonstandard behavior. Further, this is the generally accepted way to bring a type into a namespace when multiple options are otherwise possible, so it is not unique to the usage of size_t.

This isn't really something that a person can authoritatively answer. I've been a professional developer for 10 years, and have worked with C++ since 1998, but I will never see any statistically significant portion of the total C++ code that's been written. From what I have seen, there is plenty of code out there that still uses stddef.h, and it won't likely break anytime soon.

For new code, I prefer just typing the "std::" prefix everywhere, only applying the using directives when it becomes cumbersome or difficult to read. However, I recognize that this can be irritating for "inherited" code, which is where the file-scope using directives are better. If you have the time to properly refactor the inherited code, there's a good argument that you should do so, but it's very likely to involve more than just the size_t variables.

I should also mention that the C++ FAQ (item 27.5) mentions this concern as well here, where I got the impression they mostly recommend consistency with others on your team.

I want to note here that it is NOT good practice to apply "using namespace std" at the file scope, though this would also bring size_t into the global namespace. I will link the reason for that here.

I seem to have scared tuple_cat off (sorry), but I really did think his empirical method was good, so I'm trying to incorporate some changes to resolve my concerns with his answer. I tried searching github with the following modified queries, which admittedly still may have some issues:

A) "size_t" AND "stddef.h" language:c++
B) "std::size_t" AND "<cstddef>" language:c++
C) "size_t" AND "<cstddef>" AND NOT "std::size_t" language:c++
D) "size_t" AND "<cstddef>" AND "using namespace std" AND NOT "std::size_t" language:c++
E) "size_t" AND "<cstddef>" AND "using std::size_t" language:c++

I get the following:

  • A) 974,239 results (stddef.h approach)
  • B) 1,230,021 results (cstddef approach, with "std::" prefixes)
  • C) 469,721 results (cstddef approach, no prefixes)
  • D) 32,539 results (cstddef approach, "using namespace std", DON'T DO THIS!)
  • E) 27,080 results (method I recommend, "using std::size_t")

It's definitely not perfect, and I welcome criticism to make it better, but it appears that the method I recommend, as stated, is not the most popular. Based on the data, it appears that the most popular is using the "std::" prefixes on size_t (B), followed by including "stddef.h" (A). Luckily, the bad approach of (D) is not popular, but it appears that many people may be relying on other files/headers to bring size_t into the global namespace, or just hoping it's already there on the compiler (C).

Therefore, to "go with the herd", you should prepend everything with "std::". If you don't want to do that, then "stddef.h" is also in very common use, but my preference is still the using directive.

like image 82
Bob Miller Avatar answered Sep 29 '22 08:09

Bob Miller