Несколько лет назад, CERT вынес консультативное о некоторых оптимизирующих компиляторов прочь указатель проверки переполнения, которые были технически не определены в стандарте C, таких как:Является ли следующий код хорошо определенным в соответствии со стандартом C99?
/* note: not the code being asked about */
#include <stdint.h>
void fn(uint32_t len) {
char buffer[BUFLEN];
if (buffer + len > buffer) { /* not defined if len > BUFLEN! */
die();
}
/* do whatever */
}
Посоветовавшись стандарт C99 теперь я интересно, если даже следующее код хорошо определен:
#include <stdlib.h>
#include <stdint.h>
int main() {
uint32_t *buf = malloc(sizeof(uint32_t) * 20);
*(buf+10) = 100;
return *(buf+10);
}
соответствующие разделы стандарта C99, казалось бы 6.5.6/7
, 6.5.6/8
и 7.20.3.3/2
. Мое чтение стандарта означает следующее:
7.20.3.3/2
не дает никаких указаний о том, что память, выделеннаяmalloc
должна рассматриваться как массив (ср7.20.3.1
дляcalloc
).- В соответствии с
6.5.6/7
в добавочном выражении указатель на объект, который не является элементом массива, ведет себя так же, как указатель на первый элемент массива длиной один. 6.5.6/8
оставляет неопределенным результат аддитивного выражения, указывающего на элемент более одного последнего элемента объекта массива. Так как6.5.6/7
указывает, что в этом аддитивном выраженииbuf
должен вести себя так же, как указатель на массив длиной один, это оставило быbuf+10
неопределенным.
Означает ли это, что второй код, указанный выше, не определен в соответствии со стандартом C99?
Нет никакого способа, чтобы стандарт преднамеренно запретил второй пример - одно из предполагаемых видов использования 'malloc()' заключается в распределении массивов. –