2014-12-03 19 views
8

Esiste un modo in C e C++ per far sì che le funzioni che restituiscono void vengano valutate in ordine non specificato?Valutazione delle funzioni non ordinata per le funzioni restituite void

So che gli argomenti delle funzioni vengono valutati in modo non specificato in modo per le funzioni non tornare vuoto questo può essere utilizzato per valutare le funzioni in ordine non specificato:

codice
#include <stdio.h> 

int hi(void) { 
    puts("hi"); 
    return 0; 
} 

int bye(void) { 
    puts("bye"); 
    return 0; 
} 

int moo(void) { 
    puts("moo"); 
    return 0; 
} 

void dummy(int a, int b, int c) {} 

int main(void) { 
    dummy(hi(), bye(), moo()); 
} 

legale C e C++ compilato da un conforme il compilatore può stampare hi, bye e moo in qualsiasi ordine. Questo è non comportamento indefinito (demoni nasali non sarebbe valido), c'è semplicemente più di uno, ma meno di infinite uscite valide e un compilatore conforme non deve nemmeno essere deterministico in ciò che produce.

C'è un modo per farlo senza i valori di ritorno fittizi?

Precisazione: Questa è una domanda astratta su C e C++. Un fraseggio originale migliore potrebbe essere stato esiste un contesto in cui l'ordine di valutazione della funzione non è specificato per le funzioni che restituiscono il nulla? Non sto cercando di risolvere un problema specifico.

+0

Se i metodi sono 'void' perché si li utilizza come parametro? – John3136

+0

Il mio obiettivo non è usarli come parametro ma valutarli in ordine non specificato. – Praxeolitic

+0

@Gyapti Il caso d'uso è curiosità. – Praxeolitic

risposta

9

Si può sfruttare il fatto che il lato sinistro di un dell'operatore virgola è un'espressione scartato valore (vuoto espressione in C) simili (see it live):

int main(void) { 
    dummy((hi(),0), (bye(),0), (moo(),0)); 
} 

Da il progetto C++ sezione standard 5.18operatore virgola:

Una coppia di espressioni separate da una virgola viene valutata da sinistra a destra; l'espressione sinistra è un'espressione di valore scartato (clausola 5).

e sezione C11 6.5.17virgola esercente:

L'operando sinistro dell'operatore virgola viene valutata come espressione vuoto; c'è un punto di sequenza tra la sua valutazione e quella dell'operando di destra. Quindi viene valutato l'operando destro ; il risultato ha il suo tipo e valore.

Come Matt sottolinea è è anche possibile mescolare il metodo di cui sopra con gli operatori aritmetici per ottenere ordine imprecisato di valutazione:

(hi(),0) + (bye(),0) + (moo(),0) ; 
+0

Mi è piaciuta questa risposta. Alcune delle cose più interessanti che ho imparato su SO sono derivate da domande controverse come questa che sembrano stupide per alcuni. – Praxeolitic

+2

Non hai bisogno di 'dummy' affatto, poiché anche l'ordine di valutazione di altri operatori non è specificato; per esempio. '(hi(), 0) + (bye(), 0) + (moo(), 0);' –

+1

@Praxeolitic Non penso che sia una domanda sciocca, di solito quando si tratta di effetti collaterali che le persone vogliono [evitare l'ordine di valutazione non specificato come la piaga] (http://stackoverflow.com/q/27158812/1708801) perché di solito si traduce in cose brutte. Quindi questa domanda richiede sicuramente un salto mentale. –

-1

Bene c'è sempre l'approccio ovvio di mettere i puntatori alle funzioni in un contenitore, mischiarlo (o come suggerito in un commento che lo ordina) e chiamare ogni elemento nel contenitore. Se hai bisogno di avere lo stesso comportamento ogni volta assicurati che il tuo seme sia lo stesso ogni volta.

+0

@Mohit Jain Puoi approfondire come un ordine casuale generato dallo stesso seme è diverso da non specificato? In entrambi i casi è possibile determinare facilmente l'ordine dopo una singola esecuzione del programma. –

+2

Anche l'ordinamento del contenitore funzionerà, poiché l'ordine degli indirizzi delle funzioni non è specificato. –

+0

@BenjaminLindley Bel rovesciamento! Quell'idea potrebbe rendere questa risposta praticabile ma evita di incorrere in UBD? Il confronto tra puntatori e funzioni è legale? Il confronto del puntatore a funzione – Praxeolitic

Problemi correlati