можно ещё и в длинную арифметику залезть
venco, 
arseniiv, не смейтесь, я же за помощью пришел.
И я привел альтернативный вариант, простой, ничему не противоречащий. Понятно же,
что если указатель плохой, то существует другая зацепка для условия цикла. Обсмеяли,
ну пусть, всё равно - спасибо.
Так вроде бы 'undefined behavior' не тоже самое, что и крэш... (но, кажется, я понял, что Вы имели ввиду).
Я не понял, 
Geen, объяснили бы. Я по-английски читаю с яндекс-переводчиком, плохо.
А Вы, 
venco, мне ответили: "Всё хорошо, всё нормально",
и сами же приводите такие ужасы, крэш и форматирование диска.
Специально подождал, пока Вы с 
Geen-ом пообсуждаете, и теперь говорю Вам
и 
Geen-у большое спасибо. Но всё же я так понял, что делать такие конструкции
можно, на свой страх и риск.
Еще есть вопросы. Они не столь важные, как первый вопрос.
Второй вопрос.
В функцию передается в качестве аргумента указатель на структуру. Структура
содержит указатели на данные. Функция перелопачивает за один вызов десятки
килобайт данных. Привожу два варианта обработки этих данных.
struct abc {
    char *p1;
    char *p2;
    char *v1;
};
int foo(struct abc *s)
{
      ....
    char *p1, *p2, *v1;
    // Вариант-1
    p1 = s->p1;
    p2 = s->p2;
    v1 = s->v1;
    while(p1 < p2){
        *v1++ = *p1++;
    }
    s->p1 = p1;
    s->p2 = p2;
    s->v1 = v1;
    // Вариант-2
    while(s->p1 < s->p2){
        *s->v1++ = *s->p1++;
    }
      ....
}
 
  Если функция громоздкая, то я применяю первый вариант, чтобы код не пестрел
этими стрелками. По-моему, без стрелок читаемее. Но у меня еще есть догадка,
что первый вариант обеспечивает большее быстродействие. Если указателей
много, и они не могут безвылазно лежать в регистрах процессора, то, как я
понимаю, чтобы добраться до данных, нужно:
-прочитать указатель на структуру, поместить его в регистр;
-прибавить к нему смещение до нужного поля стркутуры;
-из этого поля прочитать указатель, поместить его в регистр;
-прочитать данные.
Верна ли моя догадка о быстроте первого варианта?