Я написал анализатор выражений, который выдает кучу инструкций на ассемблере для x86, x64 и ARM.
Чтобы проверить это, я написал небольшое приложение, которое генерирует случайные выражения, компилирует их с помощью GCC и сравнивает результат с моим кодом, пока что все хорошо.
Теперь я хочу, чтобы мой парсер выдавал предупреждения, похожие на GCC.
Я заметил, что с GCC 5.1.0
int a = 100 + 100 | 10;
GCC предупреждает о предложении скобок вокруг |
но
int b = 100 * 100 | 10;
GCC не дает предупреждения.
но сложение и умножение имеют более высокий приоритет, чем побитовое ИЛИ, так почему бы не предупредить выражение int b =?
Я очень устал LOL, так что, возможно, что-то упустил.
Окончательный ответ может исходить только от разработчиков, но я предполагаю, что причина в том, что есть другие языки, которые имеют различные предпочтения этих операторов, и поэтому пользователи этих других языков могут неправильно интерпретировать выражение. Например в некоторые диалекты Паскаля, &
имеет тот же приоритет, что и *
а также |
имеет тот же приоритет, что и +
, так что выражение, включающее оба +
а также |
без скобок между ними может иметь различную интерпретацию (стандартная Паскаль не имеет &
или же |
, но приоритет and
а также or
в стандартном паскале следует тем же правилам). Я думаю, что, как и многие языки, копируют приоритет оператора C, другие копируют Pascal.
Это вопрос старшинство, *
приоритет 5, +
6 и |
12
Поэтому, когда вы получаете предупреждение от одного, но не от другого, вы обнаруживаете несогласованность компилятора. Или у компилятора есть правило, которое говорит, что (priorityDifference (X, Y) < 7 отображать предупреждение о парентезе, что не имеет смысла.
Опубликуйте отчет об ошибке в вашей версии.
Прочитав комментарий celtschk, я попробовал несколько выражений на C ++ и бесплатный паскаль.
C ++
a = 100 + 100 & 100; // = 64
a = (100 + 100) & 100; // = 64
Свободный Паскаль
a := 100 + 100 and 100; // = 200
a := (100 + 100) and 100; // = 64
Свободный Паскаль
a := (100 + 100) and 222; // = 200
a := 100 + 100 and 222; // = 168
// C ++
a = 100 * 100 & 222; // = 16
// Свободный Паскаль
a := 100 * 100 and 222; // = 16
Таким образом, казалось бы, что побитовые операторы в других языках могут не иметь того же уровня приоритета, что и в C ++, что может вызвать головную боль при переводе между языками. Возможно, предупреждающее сообщение, созданное GCC, могло бы быть более информативным.