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, nee 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 lhserhs 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).