Я думаю, что следующий код — это зло, но его можно скомпилировать без предупреждения.
int f(int n)
{
return n + 1;
}
int n = 0;
n = f(n++) + f(++n);
Мне просто интересно, почему Святой Стандарт не осуждает таких операторов?
Я думаю, что может быть две причины:
Один может быть для обратной совместимости;
Другой может быть для этого в некоторых случаях эти операторы очень полезны.
Если последнее верно, не могли бы вы привести несколько примеров? Благодарю.
Это больше, чем зло, это неопределенное поведение ™. Вот почему все здравомыслящие люди запрещают такое использование.
Обратная совместимость, безусловно, составляет половину проблемы — используются приращение и уменьшение везде. Они также полезны для итераторов и прочего.
Суть в том, что C ++ никогда не мешал вам стрелять себе в ногу. Это только один пример. C ++ не запрещает вещи, которые могут быть хорошими только потому, что они могут быть плохими. Не злоупотреблять ими — ваша проблема.
Чтобы удалить эти ++
а также --
операторы из C и / или C ++, безусловно, нарушат много кода — на самом деле, я подозреваю, что если вы удалите эти два оператора, почти каждый существующий исходный файл прекратит компиляцию.
Они очень полезны при правильном использовании — если вы не используете их с обеих сторон одной и той же переменной, все будет в порядке.
Этот код не скомпилируется, но добавляется скобка, чтобы сделать его (++n)++
правильно компилируется — но g ++ выдает предупреждение «операция над n может быть неопределенной».
И если мы удалим ++
а также --
оператор, как вы ожидаете написать общий для-lopp:
for(int i = 0; i < 100; i++)
как это:
for(int i = 0; i < 100; i = i + 1)
или же
for(int i = 0; i < 100; i += 1)
Запрет всего, что может быть неправильно использовано в C и C ++, в значительной степени сведет язык к нулю и, безусловно, либо сделает язык совершенно бесполезным, либо, по крайней мере, предотвратит множество допустимых применений. Это было бы как запрет на ножи, потому что люди МОГУТ их использовать (и даже использовали) для плохих вещей. Но если вы хотите резать хлеб, мясо или овощи, они делают чертовски удобные инструменты для этой цели.
Мне просто интересно, почему Святой Стандарт не осуждает таких операторов?
Потому что это совершенно правильный код, но он вызывает неуказанное поведение, поскольку порядок вычисления операндов в выражении C не указан. Единственная проблема в коде была создана программист, кто написал код, который опирается на неопределенное поведение. Это не задача стандарта C обучать программистов языку.
(Это не неопределенное поведение. См. C11 6.5.2.2. Между оценками указателя функции и фактическими аргументами в вызове функции и фактическим вызовом существует точка последовательности. Если бы не точка последовательности после оценки каждого параметра функции, это было бы неопределенным поведением, потому что вы не можете дважды модифицировать одну и ту же переменную в операции без точки последовательности между ними.)
Один может быть для обратной совместимости;
Нет. C всегда имел неопределенный порядок оценки операндов. Этот код работает так же из предстандартного K&R код полностью до C11.
Другой может быть для этого в некоторых случаях эти операторы очень полезны.
Нет, код, который вы разместили, бесполезен в любом сценарии. Он запутан и может быть написан лучшими способами для достижения той же функциональности и идентичного машинного кода более безопасным и более читабельным способом. Например:
n++;
n = f(n) + f(n);
n++;