Questa domanda è rispondente per C ++: Stroustrup, "Design ed Evolution of C ++" discute questo nella sezione 11.6.1, pp. 247-250.
Vi erano obiezioni generali sull'aggiunta di un nuovo operatore. Si aggiungerebbe alla tabella di precedenza già complicata. I membri del gruppo di lavoro pensavano che avrebbe dato solo una minima utilità rispetto ad avere una funzione, e volevano essere in grado di sostituire le proprie funzioni a volte.
Non c'era un buon candidato per un operatore. ^
è esclusivo-o, e ^^
ha invitato la confusione a causa della relazione tra &
e |
e &&
e ||
. !
non era adatto poiché ci sarebbe la naturale tendenza a scrivere !=
per l'esponenziazione di un valore esistente, e questo era già stato preso. Il migliore disponibile potrebbe essere stato *^
, che a quanto pare a nessuno piaceva davvero.
Stroustrup considera nuovamente **
, ma ha già un significato in C: a**p
è a
volte a cui p
punta a, e char ** c;
dichiara c
come puntatore al puntatore a char
. Introducendo **
come token che significa "dichiarazione di un puntatore a puntatore a", "punta su ciò che la prossima cosa punta a" (se si tratta di un puntatore) o "esponenziazione" (se seguito da un numero) ha causato problemi di precedenza. a/b**p
dovrebbe analizzare come a/(b**p)
se p fosse un numero, ma (a/b) * *p
se p fosse un puntatore, quindi questo dovrebbe essere risolto nel parser.
In altre parole, sarebbe stato possibile, ma avrebbe complicato la tabella delle precedenze e il parser, ed entrambi sono già troppo complicati.
Non conosco la storia di Java; tutto quello che potevo fare sarebbe speculare. Per quanto riguarda C, da dove è iniziato, tutti gli operatori C sono facilmente tradotti in codice assembly, in parte per semplificare il compilatore e in parte per evitare di nascondere funzionalità dispendiose in operatori semplici (il fatto che operator+()
e altri potrebbero nascondere grande complessità e prestazioni hits è stata una delle prime lamentele sul C ++).