2010-09-17 13 views
7

Sto tentando di implementare la libreria atomica dalla bozza C++ 0x. Specificamente, sto implementando §29.6/8, il negozio metodo:Implementazione atomica <T> :: archivio

template <typename T> 
void atomic<T>::store(T pDesired, memory_order pOrder = memory_order_seq_cst); 

Gli stati requisito:

L'argomento ordine non è memory_order_consume, memory_order_acquire, né memory_order_acq_rel.

Non sono sicuro di cosa fare se è uno di questi. Non dovrei fare nulla, lanciare un'eccezione, ottenere un comportamento indefinito o fare qualcos'altro?

P.S .: "C++ 0x" sembra un po 'come un pesce morto: 3

+7

+1 per un pesce morto. – GManNickG

risposta

9

fare quello che vuoi. Non importa.

Quando ISO afferma che "non si deve fare qualcosa", farlo è un comportamento indefinito. Se un utente lo fa, ha violato il contratto con l'implementazione e l'implementazione è nei suoi diritti di fare ciò che desidera.

Ciò che decidi di fare dipende interamente da te. Opterei per qualunque cosa renda la tua implementazione "migliore" (ai tuoi occhi, sia quella più veloce, più leggibile, soggetta al principio del minimo stupore, e così via).

Io stesso, mi piacerebbe avere una buona leggibilità (dato che dovrei mantenere la cosa) con velocità che si avvicina al secondo.

0

Preferisco avere un comportamento vago e sano che qualcosa di pazzo.

Bene, come potenziale consumatore della tua libreria, ecco cosa mi piacerebbe: se non ci sono costi di performance per l'utilizzo documentato, quindi vedere se uno dei valori memory_order fornisce un superset funzionale degli altri, in particolare qualcosa che corrisponde a ciò che un chiamante potrebbe ingenuamente aspettarsi che i modi non supportati facciano (se si può formulare una ragionevole aspettativa). Il chiamante può ottenere la modalità più lenta e sicura, ma è meglio di qualcosa che funziona male. Riduci la dipendenza del codice client dall'ottenere tutto perfetto per il tuo codice. Il problema con questo - rispetto a un'asserzione/eccezione - è che può passare inosservato in un ambiente di test, quindi considera anche di scrivere una spiegazione a std :: cerr, usando una variabile statica per limitare i messaggi a uno per ogni esecuzione del processo. Questa è una diagnosi molto utile.

Un'eccezione, affermazione fatale, ecc. Potrebbe far cadere un'applicazione client in un momento molto scomodo .... Sembra un po 'draconiana, e non qualcosa che apprezzerei particolarmente. Un'altra opzione è avere una variabile di ambiente che controlli questo comportamento.

(C'è presumibilmente un problema analogo per i valori che non sono nemmeno nella enumerazione corrente.)

+3

Se ti affidi a un comportamento indefinito, preferirei che la mia implementazione riformasse il tuo hard disk (che è in realtà un comportamento valido). Questo perché, mentre lo stai recuperando, non invierai il codice buggy :-) Ci può essere _no_ un comportamento funzionalmente sbagliato se è indefinito, questo è ciò che significa "indefinito". – paxdiablo

+0

@paxdiablo. Che affermazione inutile. In genere il comportamento indefinito viene invocato per errore, quindi la domanda in primo luogo. Crescere. Si chiama "programmazione difensiva", e io sono stufo di tutti i tipi di design per contratto che agiscono come cattivi ragazzi. –

+3

Quello che preferiresti ricevere è irrilevante. Lo standard afferma che non ti è permesso farlo in modo che l'implementatore sia libero di fare ciò che vuole. Potrebbero scegliere di gestirlo con garbo o potrebbero (e questa è la mia preferenza) ignorarlo e puoi correggere il tuo codice. Non sono lì per tenerti in mano se infrangi le regole. Non è diverso da chi si lamenta del fatto che 'i = ++ i + i ++;' non funziona come previsto - la risposta è _non farlo! _ E, se tu fossi quello -1'ed la mia risposta (supposizione da parte mia, ma probabilmente corretto dato il tuo tono), credo di essere "cresciuto" abbastanza da non vendicarsi. – paxdiablo

0

preferisco un errore di tempo di compilazione. Se no, allora un assert() fallimento.

L'asserzione è buona perché compila fuori dalla versione di rilascio e non influisce sulle prestazioni.

Gli errori di compilazione del tempo sono ancora migliori perché forniscono un feedback più immediato senza attendere che il software inciampi nell'errore. Le verifiche degli errori nel tempo di compilazione sono una cosa che amo del codice C++ su Python, Ruby, il codice Perl.