Unterschied zwischen size_t und std :: size_t

139

Was sind die Unterschiede zwischen size_tund std::size_tin Bezug darauf, wo sie deklariert werden, wann sie verwendet werden sollten und welche anderen Unterscheidungsmerkmale?

Mankarse
quelle
Es würde mich interessieren, ob die C ++ - Spezifikation std :: size_t mit dem Typ C size_t verknüpft.
Doug T.
Siehe ähnliche Frage: Link
Mankarse

Antworten:

88

C size_tund C ++ std::size_tsind beide gleich.

In C ist es in <stddef.h>und in C ++ definiert, in <cstddef>dessen Inhalt der C-Header identisch ist (siehe das folgende Zitat). Es ist als vorzeichenloser Integer-Typ des Ergebnisses des Operators sizeof definiert .

C Standard sagt in §17.7 / 2,

size_t ist der vorzeichenlose Integer-Typ des Ergebnisses des Operators sizeof

Und C ++ Standard sagt (über cstddefHeader) in §18.1 / 3,

Der Inhalt entspricht dem Standard-C-Bibliotheksheader mit den folgenden Änderungen .

Also ja, beide sind gleich; Der einzige Unterschied besteht darin, dass C ++ size_tim stdNamespace definiert .

Bitte beachten Sie auch, dass in der obigen Zeile auch "mit den folgenden Änderungen" steht, auf die nicht Bezug genommen wird size_t. Es bezieht sich eher auf die neuen Ergänzungen (meistens), die C ++ in der Sprache (nicht in C vorhanden) vorgenommen hat und die ebenfalls im selben Header definiert sind.


Wikipedia hat sehr gute Informationen über Reichweite und Speichergröße von size_t:

Bereich und Speichergröße von size_t

Der tatsächliche Typ von size_t ist plattformabhängig . Ein häufiger Fehler besteht darin, anzunehmen, dass size_t mit int ohne Vorzeichen identisch ist, was zu Programmierfehlern führen kann, [3] [4] beispielsweise beim Übergang von einer 32- zu einer 64-Bit-Architektur.

Gemäß dem ISO C-Standard von 1999 (C99) ist size_t ein vorzeichenloser Integer-Typ mit mindestens 16 Bit.

Und den Rest können Sie von dieser Seite auf Wikipedia lesen .

Nawaz
quelle
Das bringt zu einem anderen Q: Wenn STL bereits size_t über C (cstddef) importiert, warum hat es dann wieder eine eigene Version?
Alok Save
43
@Als: Genau genommen ist es ein Fehler, size_tohne using namespace std;oder zu sagen using std::size_t;. Die meisten Compiler erlauben dies jedoch, und der Standard erlaubt es ihnen ausdrücklich, dies zuzulassen (§D.5 / 3).
Potatoswatter
9
@ Potatoswatter: Sicherlich kann es nicht sowohl ein Fehler sein als auch im Standard ausdrücklich erlaubt sein? Wenn es im Standard ist, ist es kein Fehler!
Ben Hymers
8
@BenHymers Der Standard gibt an, was die Standardheader deklarieren, und sie dürfen keine anderen nicht reservierten Namen deklarieren. Der Header <cstddef>kann deklariert werden oder nicht ::size_t, sodass Sie sich nicht darauf verlassen können, dass er vorhanden ist oder fehlt, es sei denn, Sie enthalten ausdrücklich einen <stddef.h>anderen Header aus der C-Bibliothek, der ihn garantiert deklariert.
Potatoswatter
4
@ Potatoswatter: Ah, ich verstehe was du jetzt meinst! Ich muss durch zu viele "Erlaubnisse" in einem Satz verwirrt worden sein. Ich denke immer noch, dass Ihr erster Kommentar zu stark ist; Wie Sie gerade gesagt haben, ::size_tist zB in vorhanden <stddef.h>, so dass Sie es nicht immer mit qualifizieren müssen std::.
Ben Hymers
16

Ab C ++ 03 "17.4.3.1.4 Typen":

Für jeden Typ T aus der Standard C-Bibliothek (Fußnote 169) sind die Typen :: T und std :: T der Implementierung vorbehalten, und wenn definiert, muss :: T mit std :: T identisch sein.

Und Fußnote 169:

Diese Typen sind 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 und wint_t.

Michael Burr
quelle
Portabler Code sollte sich also nicht auf die std::Tdefinierten Varianten verlassen ?
Mankarse
5
@Mankarse: Sie sollten sich nicht darauf verlassen, dass sie definiert werden, wenn Sie nur die C-Version des entsprechenden Headers einschließen. Wenn Sie #include <stddef.h>dann std::size_tmöglicherweise verfügbar sind oder nicht. Wenn Sie #include <cstddef>dann std::size_tverfügbar sind, aber size_tmöglicherweise nicht.
Dennis Zickefoose
4
@Mankarse: Das Gegenteil. Die C ++ - Versionen der Header müssen sie in definieren, std::und der Absatz besagt, dass sie möglicherweise auch im Namespace der obersten Ebene definiert werden. Wenn dies der Fall ist, müssen sie in std::und auf oberster Ebene identisch definiert werden. Die meisten Compiler enthalten nur den C-Header und importieren die Namen in std::, sodass die Symbole in beiden definiert werden.
Jan Hudec
4
Persönlich beschäftige ich mich nie mit den <cxxxxx> -Headern oder den std::Varianten von Bezeichnern, die vom C-Ufer kommen. Ich bleibe bei <xxxxx.h>den Standard-C-Headern - es war nie ein Problem. Also würde ich verwenden <stddef.h>und size_tniemals darüber nachdenken std::size_t; Tatsächlich fällt mir nie ein, dass es eine gibt (oder geben könnte) std::size_t.
Michael Burr
12

std :: size_t ist in der Tat stddef.h ‚s size_t .

cstddef gibt Folgendes an:

#include <stddef.h>
namespace std 
{
  using ::ptrdiff_t;
  using ::size_t;
}

... die vorherige Definition effektiv in den Standard-Namespace bringen.

hifier
quelle
Wie Nawaz betont, ist es tatsächlich umgekehrt. Sie können nicht einschließen <cstddef>und erwarten zu bekommen ::size_t, aber wenn Sie einschließen, werden <stddef.h>Sie bekommen std::size_t.
MSalters
4
@ MSalters, ich folge nicht. Einschließlich <stddef.h>wird nur Sie bekommen ::size_t.
Hifier
2
Das ist also ein Fehler in Ihrer Implementierung.
MSalters
4
@ MSalters, ich folge nicht ganz. Sollte es nicht umgekehrt sein? <cstddef> kommt aus C ++, sollte also das Zeug in std :: * definieren? Andererseits würde ich in einem C-Header wie stddef.h nur den C-Typ erwarten, dh :: size_t.
Ela782
11
@ MSalters, da C ++ 11 nicht korrekt ist. Wenn Sie einschließen, werden <cstddef>Sie garantiert bekommen std::size_tund Sie könnten auch bekommen ::size_t(aber es ist nicht garantiert). Wenn Sie einschließen, werden <stddef.h>Sie garantiert bekommen ::size_tund Sie könnten auch bekommen std::size_t(aber es ist nicht garantiert). In C ++ 03 war das anders, aber das war praktisch nicht umsetzbar und wurde als Fehler behoben.
Jonathan Wakely