У чому полягають відмінності між ними size_t
та std::size_t
щодо того, де вони декларуються, коли вони повинні використовуватися та будь-які інші ознаки, що розмежовуються?
У чому полягають відмінності між ними size_t
та std::size_t
щодо того, де вони декларуються, коли вони повинні використовуватися та будь-які інші ознаки, що розмежовуються?
Відповіді:
C size_t
і C ++ std::size_t
обоє однакові.
В C він визначений в <stddef.h>
і в C ++, його визначено <cstddef>
, вміст якого такий же, як і заголовка C (див. Цитата нижче). Її визначають як ціле число без знака типу в результаті цього SIZEOF оператора.
C Стандарт говорить у §17.7 / 2,
size_t , який є цілим числом без знака типу в результаті цього SIZEOF оператора
А C ++ Standard (про cstddef
заголовок) говорить у § 18.1 / 3,
Вміст такий самий, як у заголовку бібліотеки Standard C, із наступними змінами .
Так так, обидва однакові; Єдина відмінність полягає в тому, що C ++ визначає size_t
у std
просторі імен.
Також зверніть увагу, що у наведеному вище рядку також написано "із наступними змінами", на які не йдеться size_t
. Її швидше стосуються нових доповнень (здебільшого), внесених C ++ до мови (немає в С), які також визначені в одному заголовку.
У Вікіпедії є дуже хороша інформація про діапазон і розмір пам’яті size_t:
Діапазон і розмір зберігання size_t
Фактичний тип size_t є залежить від платформи ; поширена помилка полягає в припущенні size_t таким же , як беззнаковий Int, що може привести до помилок програмування, [3] [4] при переході від 32 до 64-бітної архітектури, наприклад.
Відповідно до стандарту ISO C 1999 (C99), розмір_t є цілочисловим типом без підпису принаймні 16 біт.
А решту ви можете прочитати з цієї сторінки на wikipedia.
size_t
без using namespace std;
або using std::size_t;
. Однак більшість компіляторів дозволяє це, а Стандарт спеціально дозволяє їм це дозволити (§D.5 / 3).
<cstddef>
може або не може задекларувати ::size_t
, тому ви не можете розраховувати на те, що він там присутній або відсутній, якщо спеціально не включити <stddef.h>
або інший заголовок з бібліотеки С, який гарантовано оголошує його.
::size_t
наприклад, в <stddef.h>
, тому вам не завжди потрібно це кваліфікувати std::
.
Від C ++ 03 "17.4.3.1.4 Види":
Для кожного типу T з бібліотеки Standard C (виноска 169) типи :: T і std :: T зарезервовані для реалізації, і, коли вони визначені, :: T повинні бути ідентичними std :: T.
І виноска 169:
Це типи clock_t, div_t, FILE, fpos_t, lconv, ldiv_t, mbstate_t, ptrdiff_t, sig_atomic_t, size_t, time_t, tm, va_list, wctrans_t, wctype_t та wint_t.
std::T
варіанти?
#include <stddef.h>
тоді std::size_t
могли б або не можуть бути недоступні. Якщо ви #include <cstddef>
тоді std::size_t
є, але size_t
може бути і не.
std::
а в абзаці говориться, що він також може визначати їх у просторі імен верхнього рівня, і якщо це так, він повинен визначати їх однаково у std::
верхньому та верхньому рівнях. Більшість компіляторів просто містять заголовок C та імпортують імена std::
, тому символи в кінцевому підсумку визначені в обох.
std::
варіантами ідентифікаторів, які надходять з берега С. Я дотримуюся <xxxxx.h>
стандартних заголовків C - це ніколи не було проблемою. Таким чином, я хотів би використовувати <stddef.h>
і size_t
і ніколи не дають другий думки до std::size_t
; насправді мені ніколи не спадає на думку, що є (або може бути) std::size_t
.
станд :: size_t фактично stddef.h «s size_t .
cstddef дає наступне:
#include <stddef.h>
namespace std
{
using ::ptrdiff_t;
using ::size_t;
}
... ефективно вводячи попереднє визначення в простір імен std.
<cstddef>
і очікувати отримання ::size_t
, але якщо включите <stddef.h>
, то отримаєте std::size_t
.
<stddef.h>
ви отримаєте лише вас ::size_t
.
<cstddef>
ви гарантовано отримаєте std::size_t
і ви також можете отримати ::size_t
(але це не гарантується). Якщо ви включите, <stddef.h>
ви гарантовано отримаєте ::size_t
і ви також можете отримати std::size_t
(але це не гарантується). У C ++ 03 це було інакше, але це було фактично без змін і було зафіксовано як дефект.