LINUX.ORG.RU

баг gcc?


0

0

Похоже баг:
Цикл идет не до тех пор пока встретяться \r\n\r\n А до тех пор пока не встретиться хотябы один из этих знков

#include <stdio.h>

int main(void)
{
  char *data = "qwerty\r\n\r\n";

  while(((*data != '\r') && (*(data + 1) != '\n') && (*(data + 2) != '\r') && (*(data + 3) != '\n')))
  {
    printf("%c", *data);
    data++;
  }
  printf(" => is '%c%c%c%c'\n", *data, *(data + 1), *(data + 2), *(data + 3));

  return 0;
}



Вот дизассеблировка: Обратите внимание на цикл!!! Он делает не то что нужно!!!

080483bc <main>:
#include <stdio.h>

int main(void)
{
 80483bc:       55                      push   %ebp
 80483bd:       89 e5                   mov    %esp,%ebp
 80483bf:       83 ec 08                sub    $0x8,%esp
 80483c2:       83 e4 f0                and    $0xfffffff0,%esp
 80483c5:       b8 00 00 00 00          mov    $0x0,%eax
 80483ca:       83 c0 0f                add    $0xf,%eax
 80483cd:       83 c0 0f                add    $0xf,%eax
 80483d0:       c1 e8 04                shr    $0x4,%eax
 80483d3:       c1 e0 04                shl    $0x4,%eax
 80483d6:       29 c4                   sub    %eax,%esp
  char *data = "qwerty\r\n\r\n";
 80483d8:       c7 45 fc 88 85 04 08    movl   $0x8048588,0xfffffffc(%ebp)

 80483df:       c7 45 f8 00 00 00 00    movl   $0x0,0xfffffff8(%ebp)
  while(((*data != '\r') && (*(data + 1) != '\n') && (*(data + 2) != '\r') && (*(data + 3) != '\n')))
  {
    printf("%c", *data);
 80483e6:       8b 45 fc                mov    0xfffffffc(%ebp),%eax
 80483e9:       80 38 0d                cmpb   $0xd,(%eax)
 80483ec:       74 44                   je     8048432 <main+0x76>
 80483ee:       8b 45 fc                mov    0xfffffffc(%ebp),%eax
 80483f1:       40                      inc    %eax
 80483f2:       80 38 0a                cmpb   $0xa,(%eax)
 80483f5:       74 3b                   je     8048432 <main+0x76>
 80483f7:       8b 45 fc                mov    0xfffffffc(%ebp),%eax
 80483fa:       83 c0 02                add    $0x2,%eax
 80483fd:       80 38 0d                cmpb   $0xd,(%eax)
 8048400:       74 30                   je     8048432 <main+0x76>
 8048402:       8b 45 fc                mov    0xfffffffc(%ebp),%eax
 8048405:       83 c0 03                add    $0x3,%eax
 8048408:       80 38 0a                cmpb   $0xa,(%eax)
 804840b:       75 02                   jne    804840f <main+0x53>
 804840d:       eb 23                   jmp    8048432 <main+0x76>
    data++;
  }
 804840f:       83 ec 08                sub    $0x8,%esp
 8048412:       8b 45 fc                mov    0xfffffffc(%ebp),%eax
 8048415:       0f be 00                movsbl (%eax),%eax
 8048418:       50                      push   %eax
 8048419:       68 93 85 04 08          push   $0x8048593
 804841e:       e8 c5 fe ff ff          call   80482e8 <printf@plt>
 8048423:       83 c4 10                add    $0x10,%esp
  printf(" => is '%c%c%c%c'\n", *data, *(data + 1), *(data + 2), *(data + 3));
 8048426:       8d 45 fc                lea    0xfffffffc(%ebp),%eax
 8048429:       ff 00                   incl   (%eax)

 804842b:       8d 45 f8                lea    0xfffffff8(%ebp),%eax
 804842e:       ff 00                   incl   (%eax)
 8048430:       eb b4                   jmp    80483e6 <main+0x2a>
  return 0;
}

anonymous

советую подучить матлогику!

while(((*data != '\r') && (*(data + 1) != '\n') && (*(data + 2) != '\r') && (*(data + 3) != '\n')))

не эквивалентно 

while(!(     *data=='\r' &&
         *(data+1)=='\n' &&
         *(data+2)=='\r' &&
         *(data+3)=='\n' ))

anonymous
()

Кажись это тебя заглючило :)

((*data != '\r') && (*(data + 1) != '\n') && (*(data + 2) != '\r') && (*(data + 3) != '\n'))

тебе вроде надо

((*data != '\r') || (*(data + 1) != '\n') || (*(data + 2) != '\r') || (*(data + 3) != '\n'))

welkam ★★
()
Ответ на: комментарий от anonymous

2anonymous (*) (07.04.2006 8:46:23)

Объясни тогда мне почему так работает:

while(1)
{
if((*data == '\r') && (*(data + 1) == '\n') && (*(data + 2) == '\r') && (*(data + 3) == '\n'))
break;
...
}

тоже матлогика???

Если сравнение вынести в тело цикла, то все ОК!

anonymous
()
Ответ на: комментарий от anonymous

>тоже матлогика???

именно

>Если сравнение вынести в тело цикла, то все ОК!

а ты подумай

while (A!=C1 && B!=C2)
;

while (1) {
if (A==C1 && B==C2)
break;
}

совершенно разные вещи,

да и скобки вокруг лишние
if(*data == '\r' && *(data + 1) == '\n' && *(data + 2) == '\r) && *(data + 3) == '\n')

fghj ★★★★★
()
Ответ на: комментарий от anonymous

Дистретная математика рулит

Отрицание коньюнкции есть дизъюнкция отрицаний

и наоборот...

sergej ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.