Es sieht für mich wie das folgende Programm einen ungültigen Zeiger berechnet, da NULL
für alles andere als Zuordnung und Vergleich für Gleichheit ist nicht gut:Führt die Arithmetik einen Nullzeiger undefiniertes Verhalten aus?
#include <stdlib.h>
#include <stdio.h>
int main() {
char *c = NULL;
c--;
printf("c: %p\n", c);
return 0;
}
Jedoch scheint es, wie keine der Warnungen oder Instrumentierungen in GCC oder Clang, das auf undefiniertes Verhalten abzielt, sagt, dass dies tatsächlich UB ist. Ist diese Arithmetik tatsächlich gültig und ich bin zu pedantisch, oder ist das ein Mangel an Kontrollmechanismen, die ich melden sollte?
Geprüft:
$ clang-3.3 -Weverything -g -O0 -fsanitize=undefined -fsanitize=null -fsanitize=address offsetnull.c -o offsetnull
$ ./offsetnull
c: 0xffffffffffffffff
$ gcc-4.8 -g -O0 -fsanitize=address offsetnull.c -o offsetnull
$ ./offsetnull
c: 0xffffffffffffffff
Es scheint ziemlich gut, dass AddressSanitizer dokumentiert zu werden, wie durch Clang verwendet und GCC konzentriert sich mehr auf dereferenzieren schlechter Zeiger, so dass fair genug ist. Aber auch die anderen Kontrollen nicht fangen es entweder: -/
bearbeiten: Ein Teil des Grundes, dass ich diese Frage gestellt ist, dass die -fsanitize
Fahnen dynamische Kontrollen von gut Definiert in dem generierten Code ermöglichen. Ist das etwas, was sie hätten fangen sollen?
Die Ausführung von Arithmetik für jeden Zeiger, der nicht Teil eines Arrays ist, ist UB, mit Ausnahme von +1 für Zeiger, die nicht über den Array hinausgehen. – chris
Der Compiler betrachtet nur eine Zeile nach der anderen, also hat er keine Ahnung, dass c NULL ist. Etwas wie LINT würde dies jedoch erfassen. Bei diesem Programm wird die c-Variable niemals dereferenziert, so dass nichts Ungültiges passiert. Es ist völlig in Ordnung, dies zu tun, und der Vorteil ist, dass Sie jetzt sehen können, dass Sie auf einem 64-Bit-System aufgrund aller f laufen! (vielleicht der Punkt des Programms?) –
@ c.fogelklou: Sie haben den Punkt völlig verpasst, und sollten lesen, was von anderen ziemlich sorgfältig gepostet wird - sie bestätigen, dass das Bilden dieses Zeigers ein undefiniertes Verhalten ist, egal was irgendjemandes Compiler tut es tatsächlich. – Novelocrat