Ниже приводится демонстрационный пример, который можно погонять на различных Си/Си++ компиляторов, с неизменностью получая один и тот же результат.
main()
{
char buf; char* p_buf[2]; char **p;
#define INIT buf=0x66; *p_buf=&buf; *(p_buf+1)=&buf; p=&p_buf;
INIT;
printf("char **p;\n");
printf("p = %p; *p = %p; **p = %x\n\n",p, *p, **p);
*p[0]++; printf("*p[0]++;\n");
printf("p = %p; *p = %p; **p = %x\n",p, *p, **p);
printf("смотрите, увеличилось _не_ содержимое **p,\n");
printf("а указатель, на который ссылается *p!\n");
printf("т.е. мы получили _совсем_ не то, что хотели!\n\n");
INIT;
(*p)[0]++; printf("(*p)[0]++;\n");
printf("p = %p; *p = %p; **p = %x;\n",p, *p, **p);
printf("хорошо, заключаем *p в скобки, тем самым явно\n");
printf("навязывая компилятору последовательность действий\n\n");
INIT;
*p[0]+=1; printf("*p[0]+=1;\n");
printf("p = %p; *p = %p; **p = %x;\n",p, *p, **p);
printf("забавно, но замена оператора ++ на оператор +=\n");
printf("эту проблему как рукой снимает!\n");
}
Листинг 3 демонстрационный пример pdp.c
Рисунок 2результат прогона pdp.exe