Prendo l'aggettivo "tecnico" per indicare comportamenti / stranezze del linguaggio ed effetti collaterali del compilatore come l'esecuzione del codice generato.
A tal fine, la risposta è: no (*). Il simbolo (*) è "consultare il manuale del processore". Se si lavora con alcuni sistemi RISC o FPGA perimetrali, potrebbe essere necessario controllare quali istruzioni vengono generate e quanto costano. Ma se si sta utilizzando praticamente qualsiasi architettura moderna convenzionale, quindi non c'è una significativa differenza di livello di processore di costo tra lt
, eq
, ne
e gt
.
Se si utilizza un caso limite si potrebbe trovare che !=
richiede tre operazioni ( cmp
, not
, beq
) contro due ( cmp
, blt xtr myo
). Ancora una volta, RTM in quel caso.
Per la maggior parte, i motivi sono difensivi / indurenti, specialmente quando si lavora con puntatori o loop complessi. Tener conto di
// highly contrived example
size_t count_chars(char c, const char* str, size_t len) {
size_t count = 0;
bool quoted = false;
const char* p = str;
while (p != str + len) {
if (*p == '"') {
quote = !quote;
++p;
}
if (*(p++) == c && !quoted)
++count;
}
return count;
}
Un esempio meno elaborato sarebbe dove si utilizzano i valori di ritorno per eseguire incrementi, accettando i dati da un utente:
#include <iostream>
int main() {
size_t len = 5, step;
for (size_t i = 0; i != len; ) {
std::cout << "i = " << i << ", step? " << std::flush;
std::cin >> step;
i += step; // here for emphasis, it could go in the for(;;)
}
}
Prova questo e inserisci i valori 1, 2, 10, 999.
Si potrebbe impedire questo:
#include <iostream>
int main() {
size_t len = 5, step;
for (size_t i = 0; i != len; ) {
std::cout << "i = " << i << ", step? " << std::flush;
std::cin >> step;
if (step + i > len)
std::cout << "too much.\n";
else
i += step;
}
}
Ma quello che probabilmente volevi era
#include <iostream>
int main() {
size_t len = 5, step;
for (size_t i = 0; i < len; ) {
std::cout << "i = " << i << ", step? " << std::flush;
std::cin >> step;
i += step;
}
}
C'è anche una sorta di orientamento alla convenzione <
, perché spesso si fa affidamento sull'ordinamento in contenitori standardoperator<
, ad esempio, l'hashing in diversi contenitori STL determina l'uguaglianza dicendo
if (lhs < rhs) // T.operator <
lessthan
else if (rhs < lhs) // T.operator < again
greaterthan
else
equal
Se lhs
erhs
sono una classe definita dall'utente che scrive questo codice come
if (lhs < rhs) // requires T.operator<
lessthan
else if (lhs > rhs) // requires T.operator>
greaterthan
else
equal
L'implementatore deve fornire due funzioni di confronto. Quindi <
è diventato l'operatore preferito.
i++
peri+=2
(ad esempio), verrà eseguito per un tempo molto lungo (o forse per sempre). Ora, poiché in genere si utilizza<
per quei casi in cui si incrementa l'iteratore di più di 1, è possibile utilizzare<
anche per il caso in cui si incrementa di 1 (per coerenza).