Мне кажется, что следующая программа вычисляет недопустимый указатель, так как NULL
не подходит ни для чего, кроме назначения и сравнения для равенства:
#include <stdlib.h>
#include <stdio.h>
int main() {
char *c = NULL;
c--;
printf("c: %p\n", c);
return 0;
}
Однако, похоже, что ни одно из предупреждений или инструментов в GCC или Clang, ориентированных на поведение undefined, не говорит о том, что это на самом деле UB. Действительно ли эта арифметика действительна, и я слишком педантичен, или это недостаток в механизмах проверки, о которых я должен сообщить?
Испытано:
$ 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
Похоже, что довольно хорошо документировано, что AddressSanitizer, используемый Clang и GCC, более сфокусирован на разыменовании плохих указателей, так что это достаточно справедливо. Но другие проверки не поймают его: -/
Изменить: часть причины, по которой я задал этот вопрос, заключается в том, что флаги -fsanitize
позволяют динамически проверять четкость в сгенерированном коде. Это что-то, что они должны были поймать?