2015-11-09 14 views
17

Ich fand, dass strncpy_s unter VS2013 definiert ist alsWarum ist rsize_t definiert?

errno_t __cdecl strncpy_s(_Out_writes_z_(_SizeInBytes) char * _Dst, _In_ rsize_t _SizeInBytes, _In_reads_or_z_(_MaxCount) const char * _Src, _In_ rsize_t _MaxCount); 

rsize_t ist:

typedef size_t rsize_t; 

Ich denke, es ist ein Trick von Visual Studio gemacht. Allerdings fand ich diese Funktion definiert als auf das hier page

errno_t strncpy_s(char *restrict dest, rsize_t destsz, 
       const char *restrict src, rsize_t count); 

Warum ist rsize_t definiert folgt? Was ist, wenn size_t hier verwendet wurde? Irgendwelche Sonderfälle, um dieses rsize_t zu verwenden?

+1

Ist das nicht ein visuelles studio-spezifisches 'typedef'? Es scheint nicht in meinen Header-Dateien zu erscheinen, noch scheint es in meinem Standardentwurf zu erscheinen. – skyking

+0

Vielleicht finden Sie (oder finden Sie nicht) nützliche Informationen in [Verwenden Sie die TR-24731 "Safe" -Funktionen?] (Https://stackoverflow.com/questions/372980/do-you-use-the-tr- 24731-safe-functions) Zumindest gibt es einige Probleme, die Sie beachten sollten, wenn Sie Bedenken hinsichtlich der Portabilität haben. –

Antwort

28

Sie haben es in Microsofts C++ - Standardbibliothek gefunden, aber es kommt tatsächlich von C. C 11, um genau zu sein, was bedeutet, dass es technisch kein Teil von C++ ist.

C 11-Standard, Anhang K eingeführt alle _s Funktionen und die entsprechenden typedefs, einschließlich rsize_t. Es gibt auch ein "Maximalwert" -Makro RSIZE_MAX, das groß genug für typische Anwendungen ist, aber kleiner als der tatsächliche Maximalwert des Typs. Die sicheren Funktionen machen nichts und melden einen Fehler, wenn ein Wert vom Typ rsize_tRSIZE_MAX überschreitet.

Die Idee besteht darin, Abstürze bei Pufferüberläufen und ähnlichen Fehlern zu vermeiden, die durch ungültige Größen verursacht werden, die sich normalerweise aus der Verwendung eines negativen Werts für die Größe ergeben. In der vorzeichenbehafteten Zweierkomplementdarstellung (die am häufigsten vorkommende) entspricht eine negative Zahl einer großen Zahl sehr, wenn sie als unsigniert behandelt wird. RSIZE_MAX sollte solche falsche Verwendung fangen.

den "rationalen" Teil von C11 (N1570) Zitiert, K.3.2:

3 Extrem große Objektgrößen sind häufig ein Zeichen dafür, dass die Größe eines Objekts falsch berechnet wurde.Zum Beispiel werden negative Zahlen als sehr große positive Zahlen angezeigt, wenn in einen vorzeichenlosen Typ wie size_t konvertiert wird. Einige Implementierungen unterstützen auch keine Objekte, die so groß sind wie der Maximalwert, der vom Typ size_t dargestellt werden kann.

4 Aus diesen Gründen ist es manchmal vorteilhaft, den Bereich der Objektgrößen zu beschränken, um Programmierfehler zu erkennen. Für Implementierungen, die Maschinen mit großen Adressräumen adressieren, wird empfohlen, dass RSIZE_MAX als das kleinere der Größe des größten unterstützten Objekts oder (SIZE_MAX >> 1) definiert wird, auch wenn dieses Limit kleiner ist als die Größe von einige legitime, aber sehr große, Objekte. Implementierungen, die Maschinen mit kleinen Adressräumen adressieren, möchten vielleicht RSIZE_MAX als SIZE_MAX definieren, was bedeutet, dass es keine Objektgröße gibt, die als Laufzeitbeschränkungsverletzung betrachtet wird.


Es ist erwähnenswert, dass Anhang K sehr wenige Implementierungen hat und gibt es einen Vorschlag (N1967) deprecate und/oder aus dem Standard entfernen.

+0

@zwol Ich werde das übernehmen (keine Zeit jetzt); aber ich glaube, dass Wikipedia erwähnt Open Watcom hat auch eine konforme Implementierung. – Angew

+0

@zwol: Und die MS-Implementierung ist nicht konform, oder hat sich das geändert? – Deduplicator

+0

@Deduplicator Anhang K war definitiv MS Idee, aber ich weiß nicht, ob ihre Implementierung vollständig konform ist. Es würde mich nicht überraschen, wenn sie (zum Beispiel) einen frühen Entwurf implementieren würden und dann Revisionen nicht aufgreifen könnten, weil das die Binärkompatibilität brechen würde. – zwol

13

Diese Typdefinitionen haben eine semantische Bedeutung. Natürlich können Sie size_t hier verwenden (da es die gleiche ist), aber rsize_t ist ausführlicher:

Der Typ size_t im Allgemeinen den gesamten Adressraum abdeckt. ISO/IEC TR 24731-1-2007 führt einen neuen Typ rsize_t ein, der als size_t definiert ist, aber explizit die Größe eines einzelnen Objekts enthält. [1]

Es ist die Situation ähnlich wie bei size_t statt unsigned int verwenden. Es ist im Grunde das Gleiche, aber anders benannt, so dass Sie leicht verstehen, woran Sie arbeiten (size_t = "Größe von etwas", was eine vorzeichenlose ganze Zahl impliziert).

Es ist erwähnenswert (wie von den Kommentaren vorgeschlagen), dass rsize_t in der C-Spezifikation definiert ist, aber nicht in der C++ - Spezifikation.

+0

Es könnte eine gute Idee sein, die Tatsache mit aufzunehmen, dass 'rsize_t' in der C-Spezifikation definiert ist, aber nicht in der C++ - Spezifikation. –

+2

Schöne Antwort, aber woher kommt das Zitat? –

+0

size_t, ich nehme an, es kommt von der Schriftgröße, aber rsize_t? Was bedeutet das? – sop

Verwandte Themen