Редактировать:
Что такое реальные группы выражения «3 <8? (9 <6? 7: 5): 2> 0?
4: 1 », а что означает неассоциативный в PHP?
был предложен как дубликат, но это касается PHP, а не C.
При создании тестовых примеров для небольшой программы я внес ошибку в
условная часть цикла for, например:
for(int row = 0; row < (mode == TEST) ? NO_OF_TESTS : ROWS; row++){}
(я знаю, что нужно вытащить это из цикла for
, но это не меняет проблему.)
Это приводит к ошибке сегментации, запуская конец массива как
выше приводит к бесконечному циклу.
Конечно, исправить было достаточно просто:
for(row = 0; row < ((mode == TEST) ? NO_OF_TESTS : ROWS); row++)
// ^ ^
Но меня больше интересует, как ведет себя ошибочная реализация.
Вот полный кусок кода (сам по себе не имеет смысла, так как
вырвано из контекста, но это демонстрирует проблему).
#include <stdio.h>
#include <stdlib.h>
#define TEST 0
#define INTERACTIVE 1
#define ROWS 2
#define NO_OF_TESTS 3
#define MAX_FRUIT_LEN 50
int main(void)
{
char test_cases[NO_OF_TESTS][MAX_FRUIT_LEN] =
{{"Orange"},
{"Apple"},
{"Pineapple"}};
int mode = TEST;
int row = 0;
//This fails - but in a strange way
//Uncomment this `for` loop and comment the other one to see the effects
//for(int row = 0; row < (mode == TEST) ? NO_OF_TESTS : ROWS; row++)
//With the parantheses, obviously, it works.
for(row = 0; row < ((mode == TEST) ? NO_OF_TESTS : ROWS); row++)
{
printf("Working:\tIn row %d: Mode: %d condition_eval: %d\n"
, row , mode, row < ((mode == TEST) ? NO_OF_TESTS : ROWS));
printf("Not Working:\tIn row %d: Mode: %d condition_eval: %d\n"
, row, mode, row < (mode == TEST) ? NO_OF_TESTS : ROWS);
printf("Row: %d \tFruit Name: %s\n",row, test_cases[row]);
}
printf("\nTerminating conditional evaluation (at row %d):\n", row);
printf("Working:\tIn row %d: Mode: %d condition_eval: %d\n"
, row , mode, row < ((mode == TEST) ? NO_OF_TESTS : ROWS));
printf("Not Working:\tIn row %d: Mode: %d condition_eval: %d\n"
, row, mode, row < (mode == TEST) ? NO_OF_TESTS : ROWS);
return 0;
}
Глядя на вывод и (неправильное) условное
row < (mode == TEST) ? NO_OF_TESTS : ROWS
похоже, что компилятор интерпретирует это как:
(row < (mode == TEST)) ? NO_OF_TESTS : ROWS
// ^ ^
Вопрос: почему?
Это выражение:
(mode == TEST)
можно интерпретировать как правильный операнд оператора <
или как
левый операнд оператору ?
. (Но не оба одновременно, я думаю.)
Какие правила применяются? Это вопрос приоритета оператора? Точки последовательности играют роль?
Каков порядок оценки и почему?
Я совсем запутался; любая помощь очень ценится.