2016-08-02 16 views
1

Frage:

Wenn ich zwei Zeiger haben (im Wesentlichen ein begin und ein end), die mit restrict qualifiziert sind. Der Zeiger begin wird zum Dereferenzieren/Lesen verwendet, und der Zeiger end ist ein Über-den-Ende-Zeiger, der niemals dereferenziert wird und nur zur Überprüfung der Größe des Bereichs verwendet wird (über end - begin). Sobald der Bereich verbraucht ist, erwarte ich, dass begin und end gleich sind und end - begin 0 ist, obwohl an dieser Stelle die beiden Zeiger niemals dereferenziert werden.Kann ich eingeschränkte Zeiger subtrahieren oder vergleichen?

Gibt restrict die Einschränkungen für Zeiger, ist es wohldefiniertes Verhalten zu subtrahieren und diese beiden Zeiger zu vergleichen?

MVCE:

ich einige Code haben wie folgt aus:

#include <stddef.h> 

struct Reader { 
    const char* restrict data; 
    size_t size; 
}; 

char read_char(struct Reader* reader) { 
    --reader->size; 
    return *reader->data++; 
} 

int main(int argc, char* argv[]) { 
    struct Reader reader = { 
    .data = argv[1], 
    .size = argv[1] ? strlen(argv[1]) : 0, 
    }; 

    if (reader.size > 0) { 
    return read_char(&reader); 
    } 
    return 0; 
} 

Ich möchte es so ändern, dass anstelle von sowohl data und size beim Lesen, nur data Bedürfnisse ändern zu müssen werden geändert:

#include <stddef.h> 

struct Reader { 
    const char* restrict data; 
    const char* restrict end; // Not sure if this should be restrict or not. 
}; 

char read_char(struct Reader* reader) { 
    return *reader->data++; 
} 

int main(int argc, char* argv[]) { 
    struct Reader reader = { 
    .data = argv[1], 
    .end = argv[1] + (argv[1] ? strlen(argv[1]) : 0), 
    }; 

    if (reader.end - reader.data > 0) { // Is this okay? 
    return read_char(&reader); 
    } 
    return 0; 
} 

Ist dies zulässig, da restrict ‚s Beschränkungen Zeiger?

+0

Mögliche Duplikate von [Können Sie in einigen Fällen auch eingeschränkte Zeiger verwenden, um auf dasselbe Objekt zuzugreifen?] (Http://stackoverflow.com/questions/18059205/can-you-use-restricted-po- tinters-to -access-the-self-object-in-case-1) – LPs

+0

@LPs: Meine Frage ist anders. Ich versuche nicht, über Alias-Zeiger auf dasselbe Objekt zuzugreifen. Der "end" -Zeiger wird niemals dereferenziert, und die einzige Zeit "data" und "end" alias ist, wenn sie gleich sind (zu diesem Zeitpunkt wäre die Dereferenzierung sowieso ein undefiniertes Verhalten). Meine Frage besteht darin, die beiden Zeiger zu vergleichen, was anders ist. – Cornstalks

+0

In vorgeschlagenen Duplikat wird gezeigt, dass das Verhalten definiert ist, solange Sie das spitze Objekt nicht ändern. Vermutlich vermisse ich etwas ... – LPs

Antwort

5

TL; DR: Ihre Verwendung ist zulässig, wenn ich den Standard lese.

Die Anforderungen des Standards für die Verwendung von restrict -qualifizierten Zeigern haben alle mit Aliasing und Zugriff auf das pointed-Objekt zu tun. Ich finde keine Einschränkungen bei der Verwendung solcher Zeiger als Operanden des Zeiger-Differenzoperators (-), und solche Beschränkungen wären nicht konsistent mit dem Zweck von restrict (was größere Möglichkeiten zur Optimierung bietet).

Im Gegensatz dazu basiert ein Zeigerwert, der von einem restrict -qualifizierten Zeiger durch Addition einer Ganzzahl erhalten wird, auf dem ursprünglichen Zeiger in einer Bedeutung, die für den Standard signifikant ist. Grob gesagt ist es akzeptabel, über einen solchen Zeiger auf das zu zeigende Objekt zuzugreifen, während es nicht akzeptabel ist, auf dieses Objekt über einen Zeiger auf dasselbe Objekt zuzugreifen, das nicht auf dem beschränkten Zeiger "basiert".

Darüber hinaus glaube ich nicht Reader.end muss restrict -qualifiziert werden, und ich glaube nicht, dass eine solche Qualifikation Ihnen überhaupt hilft. Sie müssen jedoch sicherstellen, dass weder Reader.end noch ein davon abgeleiteter Zeiger für den Zugriff auf die Daten verwendet wird. Sie müssen dafür nur Reader.data verwenden. In main() auch. Auf der anderen Seite, so ziemlich alles, was Sie tun können, wenn Sie nirgends das pointed-Objekt ändern.