Имеет ли" std::size t " смысл в C++?
в некотором коде, который я унаследовал, я вижу частое использование size_t
С std
квалификатор пространства имен. Например:
std::size_t n = sizeof( long );
она компилируется и работает нормально, конечно. Но мне кажется, что это плохая практика (возможно, перенесенная из C?).
правда ли, что size_t
встроен в C++ и, следовательно, в глобальном пространстве имен? Это заголовочный файл Include нужно использовать size_t
в C++?
другой способ задать этот вопрос: будет ли следующее программа (с нет включает в себя) можно ожидать compile на все компиляторы C++?
size_t foo()
{
return sizeof( long );
}
8 ответов
кажется, есть путаница среди толпы stackoverflow в отношении этого
::size_t
определяется в заголовке обратной совместимости stddef.h
. Это было частью ANSI/ISO C
и ISO C++
С самого начала. Каждая реализация C++ должна поставляться с stddef.h
(совместимость) и cstddef
где только последний определяет std::size_t
и не обязательно ::size_t
. См. приложение D к стандарту C++.
В разделе 17.4.1.2 стандарта C++, пункт 4, говорится, что:
" однако в стандартной библиотеке C++ объявления и определения (за исключением имен, определенных как макросы в C) находятся в области пространства имен (3.3.5) пространства имен std."
Это включает в себя элементы, найденные в заголовках шаблона cname, включая cstddef, который определяет значение size_t.
Так std:: size_t на самом деле правильно.
вы можете узнать size_t
в глобальном пространстве имен, в том числе, например, <stddef.h>
вместо <cstddef>
. Я не вижу никакой очевидной выгоды, и функция устарела.
size_t не встроен в C++. И он не определен по умолчанию. Это не компилируется с GCC:
int main(int argc, char** argv) {
size_t size;
}
тем не менее, size_t является частью POSIX, и если вы используете только основные вещи, такие как <cstdlib>
, вы, вероятно, в конечном итоге, это определило.
вы можете утверждать, что std::size_t является эквивалентом size_t на C++. Как отметил Брайан, std:: используется как пространство имен, чтобы избежать установки глобальных переменных, которые не подходят всем. Это так же, как std:: string, который также может были определены в корневом пространстве имен.
std::size_t n = sizeof( long );
На самом деле, вы не спросили, что конкретно кажется плохой практикой в приведенном выше. Использование size_t, квалификация с пространством имен std,...
Как говорит стандарт C++ (18.1), size_t-это тип, определенный в стандартном заголовке. Я бы предложил отбросить любые мысли и впечатления о возможном наследовании от языка C. C++ - это отдельный и другой язык, и его лучше рассматривать как таковой. Он имеет собственную стандартную библиотеку и все элементы C++ В стандартной библиотеке определены в пространстве имен std. Однако можно использовать элементы стандартной библиотеки C в программе c++.
Я бы рассмотрел включение как грязный хак. Стандарт C++ утверждает, что содержимое заголовков одинаковое или основано на соответствующих заголовках из стандартной библиотеки C, но в ряде случаев были применены изменения. Другими словами, это не прямая копия и вставка заголовков C в заголовки c++.
size_t не является встроенным типом в С.++ Это тип, определенный для указания того, какой интегральный тип используется в качестве возвращаемого типа оператора sizeof (), поскольку фактический возвращаемый тип sizeof () определен реализацией, поэтому стандарт C++ унифицируется путем определения size_t.
будет ли следующая программа (без includes) ожидается компиляция на все компиляторы C++?
size_t foo() { return sizeof( long ); }
стандарт C++ говорит (1.4):
имена, определенные в области видимости пространства имен библиотеки (7.3). Блок перевода C ++ (2.1) получает доступ к этим именам, включая соответствующий заголовок стандартной библиотеки (16.2).
size_t-это имя, определенное в пространстве имен std, поэтому каждая программа, использующая это имя, должна включать соответствующий заголовок.
далее в главе 3.7.3 говорится:
однако, ссылаясь на std, std:: bad_alloc и std:: size_t неправильно сформирован, если имя не было объявлено путем включения соответствующий заголовок.
учитывая это, программа, использующая size_t, но не включающая заголовок, плохо сформирована.
иногда другие библиотеки определяют свой собственный size_t. Например, boost. std:: size_t указывает, что вы определенно хотите стандартный c++.
size_t является стандартным типом c++ и определяется в пространстве имен std.
заголовки компилятора GNU содержат что-то вроде
typedef long int __PTRDIFF_TYPE__; typedef unsigned long int __SIZE_TYPE__;
затем stddef.ч constains что-то вроде
typedef __PTRDIFF_TYPE__ ptrdiff_t; typedef __SIZE_TYPE__ size_t;
и, наконец, файл cstddef содержит что-то вроде
#include <stddef.h> namespace std { using ::ptrdiff_t; using ::size_t; }
Я думаю, что это должно прояснить. Как долго, как вы включите
typedef long int ptrdiff_t; typedef unsigned long int size_t; namespace std { using ::ptrdiff_t; using ::size_t; }
Я думаю, что разъяснения достаточно ясны. The std::size_t
имеет смысл в C++ и ::size_t
сделайте (по крайней мере) здравый смысл в C.
однако вопрос остается. А именно, можно ли с уверенностью предположить, что ::size_t
и std::size_t
совместимы?
С чистой точки зрения typesafe они не обязательно идентичны, если где-то не определено, что они должны быть идентичными.
Я думаю, что многие используют что-то a la:
----
// a.hpp
#include <string>
void Foo( const std::string & name, size_t value );
-----
// a.cpp
#include "a.hpp"
using namespace std;
void Foo( const string & name, size_t value )
{
...
}
так в заголовок вы определенно используете ::size_t
в то время как в исходном файле, который вы будете использовать std::size_t
. Значит, они должны быть совместимы, верно? В противном случае вы получите ошибку компилятора.
/Майкл С.