Perché il tipo booleano in C ++ supporta ++ ma non -?


29

Perché l'operatore --non esiste per bool mentre lo fa per l'operatore ++?

Ho provato in C ++ e non so se la mia domanda si applica a un'altra lingua. Sarò felice di saperlo anche.

Lo so , posso usare l'operatore ++con un bool. Rende qualsiasi bool uguale a vero.

bool b = false;
b++;
// Now b == true.

Perché non possiamo usare l'operatore --in modo opposto?

bool b = true;
b--;
// Now b == false;

Non è molto utile, ma sono curioso.


8
Questa domanda su StackOverflow potrebbe essere illuminante.
Blrfl

Quindi la ragione della storia. Grazie per il link. Puoi scrivere una risposta e la metto come risolta?
aloisdg dice Reinstate Monica il

I collegamenti da soli non danno buone risposte e non esiste un buon meccanismo per contrassegnare questa domanda come un duplicato di qualcosa su un altro sito SE.
Blrfl

1
Quindi dovremmo aprire un argomento in meta.stackexchange.com o qualcosa del genere. Penso che dovresti ottenere un po 'di karma per il buon collegamento e se qualcuno ti vota, l'autore della risposta originale dovrebbe ottenere un po' di karma. In effetti, anche la domanda originale dovrebbe avere del karma.
aloisdg dice Reinstate Monica il

2
I duplicati tra siti @aloisdg sono un vecchio problema di MSO. Insegui le domande collegate per avere una visione più completa.

Risposte:


53

Ai vecchi tempi di C, non esisteva un tipo booleano. Le persone lo usavano intper l'archiviazione di dati booleani e funzionava principalmente. Zero era falso e tutto il resto era vero.

Ciò significava che se avessi preso un int flag = 0;e in seguito flag++il valore sarebbe vero. Funzionerebbe indipendentemente dal valore del flag (a meno che non lo facessi molto, si capovolgesse e tornassi a zero, ma lo ignoriamo) - incrementare il flag quando il suo valore era 1 darebbe 2, che era comunque vero.

Alcune persone lo hanno usato per impostare incondizionatamente un valore booleano su true. Non sono sicuro che sia mai diventato idiomatico , ma è in qualche codice.

Questo non ha mai funzionato --, perché se il valore fosse diverso da 1 (che potrebbe essere), il valore non sarebbe comunque falso. E se fosse già falso ( 0) e hai fatto un operatore di decremento su di esso, non rimarrebbe falso.

Quando si spostava il codice da C a C ++ nei primi tempi, era molto importante che il codice C incluso in C ++ fosse ancora in grado di funzionare. E così nelle specifiche per C ++ (sezione 5.2.6 (è a pagina 71)) si legge:

Il valore ottenuto applicando un postfix ++ è il valore che l'operando aveva prima di applicare l'operatore. [Nota: il valore ottenuto è una copia del valore originale] L'operando deve essere un valore modificabile. Il tipo di operando deve essere un tipo aritmetico o un puntatore a un tipo di oggetto completo. Dopo aver notato il risultato, il valore dell'oggetto viene modificato aggiungendo 1 ad esso, a meno che l'oggetto non sia di tipo bool, nel qual caso è impostato su true. [Nota: questo uso è obsoleto, vedere l'allegato D.]

L'operando di postfix - viene decrementato in modo analogo all'operatore postfix ++, tranne per il fatto che l'operando non deve essere di tipo bool.

Questo è di nuovo menzionato nella sezione 5.3.2 (per l'operatore prefisso - 5.2.6 era su postfix)

Come puoi vedere, questo è obsoleto (allegato D nel documento, pagina 709) e non dovrebbe essere usato.

Ma ecco perché. E a volte potresti vedere il codice. Ma non farlo.


5
"Alcune persone lo hanno usato per impostare incondizionatamente un valore booleano su true." Chiamiamoli dannatamente sciocchi, non persone.
Deduplicatore

@Deduplicatore: forse era una questione di prestazioni: caricare un valore in una variabile potrebbe aver richiesto più cicli del processore che incrementare la variabile. Naturalmente, questo probabilmente non ha importanza sui computer moderni.
Giorgio,

1
@Giorgio è abbastanza probabile. Ricorda che C è stato scritto per corrispondere strettamente al set di istruzioni PDP-7 e che il PDP-11 ha avuto altre modifiche. Da questo - "Le persone spesso immaginano che siano state create per utilizzare le modalità di indirizzo auto-incremento e auto-decremento fornite dal DEC PDP-11 su cui C e Unix sono diventate popolari per la prima volta. Questo è storicamente impossibile, dal momento che non c'era PDP- 11 quando fu sviluppato B. Il PDP-7, tuttavia, aveva alcune celle di memoria a "auto-incremento", con la proprietà che un riferimento di memoria indiretta attraverso di esse aumentava la cella. "

@Deduplicator: nel codice che utilizza numeri interi per i booleani, una variabile che viene incrementata per ogni ... qualunque cosa ... può agire sia come contatore (quante volte è stato incrementato) sia come booleano (è stato incrementato del tutto o non).
Keith Thompson,


1

Per comprendere il significato storico di questa domanda, è necessario considerare il caso del Therac-25. Il Therac-25 era un dispositivo medico che emetteva radiazioni per i malati di cancro. È stato afflitto da cattive pratiche di programmazione che hanno contribuito al suo scarso track record di sicurezza (con più morti attribuite ad esso).

http://courses.cs.vt.edu/professionalism/Therac_25/Therac_1.html

(vai a fondo pagina 3)

Ogni passaggio attraverso la routine Test di configurazione aumenta il controllo della posizione del collimatore superiore, una variabile condivisa chiamata Class3. Se Class3 è diverso da zero, c'è un'incoerenza e il trattamento non deve procedere. Un valore zero per Class3 indica che i parametri rilevanti sono coerenti con il trattamento e il raggio non è inibito.

...

Durante l'installazione della macchina, il Test di configurazione verrà eseguito diverse centinaia di volte poiché si riprogramma se stesso in attesa che si verifichino altri eventi. Nel codice, la variabile Class3 viene incrementata di uno in ogni passaggio attraverso il Test di configurazione. Poiché la variabile Class3 è 1 byte, può contenere solo un valore massimo di 255 decimali. Pertanto, ad ogni 256 ° passaggio attraverso il codice Test di configurazione, la variabile trabocca e ha un valore zero. Ciò significa che ad ogni 256 ° passaggio del test di configurazione, il collimatore superiore non verrà controllato e non verrà rilevato un errore del collimatore superiore. La sovraesposizione si è verificata quando l'operatore ha premuto il pulsante "set" nel momento esatto in cui Class3 è passato a zero. Pertanto Chkcol non è stato eseguito e F $ mal non è stato impostato per indicare che il collimatore superiore era ancora in posizione di luce di campo. Il software ha attivato i 25 MeV completi senza l'obiettivo in posizione e senza scansione. Ne conseguì un fascio di elettroni altamente concentrato, che fu disperso e deviato dallo specchio in acciaio inossidabile che si trovava sul percorso.

Il Therac-25 utilizzava qualcosa di simile all'equivalente di operator++a bool. Tuttavia, il linguaggio di programmazione utilizzato non era C ++ e il loro tipo di dati non lo era bool. A differenza della garanzia in C ++, tuttavia, un normale tipo intero continua semplicemente a salire. Il loro tipo di dati era l'equivalente diuint8_t .

C ++ ha deciso di mantenere il controllo operator++per le persone abituate a programmare in questo modo, ma invece di incrementare il valore, lo imposta semplicemente sutrue per impedire cose come questa.

Nota che operator++(bool) è obsoleto.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf

Allegato D di C ++ 14:

D.1 Operatore di incremento con operando bool
L'utilizzo di un operando di tipo bool con l'operatore ++ è obsoleto (vedere 5.3.2 e 5.2.6).


Mentre questo spiegherebbe perché è deprecato, non spiega perché esiste in primo luogo.

Esiste perché c'erano alcune persone che hanno impostato un valore booleano incrementandolo quando la programmazione in C. C ++ è stata progettata per facilitare la transizione da C, quindi l'hanno supportata con il booltipo. Stavo solo cercando di dare un esempio storico di quando le persone hanno programmato in questo modo.
David Stone,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.