2014-12-03 177 views
8

在C和C++中有沒有辦法使返回的函數返回void以未指定的順序進行評估?無返回函數的函數評估返回void

我知道,函數的參數中未指定的順序進行評估,以便對功能不返回無效這可以用來評估在指定順序的功能:由符合編譯

#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()); 
} 

合法的C和C++代碼編譯器可以以任何順序打印hibyemoo。這是而不是未定義的行爲(鼻惡魔不會有效),只有不止一個,但少於無限的有效輸出和一個兼容的編譯器甚至不需要確定它的產生。

有沒有辦法做到這一點,沒有虛擬的返回值?

澄清:這是一個關於C和C++的抽象問題。更好的原始措辭可能是有沒有任何上下文中函數評估順序未指定返回void的函數?我並不是想解決一個特定的問題。

+0

如果方法'void'爲什麼你會使用它們作爲參數? – John3136 2014-12-03 04:40:04

+0

我的目標不是將它們用作參數,而是以未指定的順序對它們進行評估。 – Praxeolitic 2014-12-03 04:40:35

+0

@Gyapti用例是好奇心。 – Praxeolitic 2014-12-03 04:41:21

回答

9

可以採取的一個事實,即一個逗號操作者的左手側是丟棄值表達式(在Cvoid表達式)這樣的(see it live)優點:

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

從的草案C++標準部5.18逗號運算符

一對由分隔的表達式逗號從左到右進行評估;左表達式是一個丟棄值表達式(第5章)。

和C11部6.5.17逗號運算符

逗號操作者的左操作數被評價爲空隙表達;在它的評估和右操作數的評估之間有一個 序列點。然後評估右邊的 操作數;結果有它的類型和價值。

馬特指出的是,也可以混合使用算術運算符上面的方法來實現評價的未指定的順序:

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

我很喜歡這個答案。我在SO上學到的一些更有趣的事情源自這樣的有爭議的問題,這對一些人來說似乎很愚蠢。 – Praxeolitic 2014-12-03 05:06:08

+2

根本不需要'dummy',因爲其他操作符的評估順序也沒有指定;例如'(hi(),0)+(bye(),0)+(moo(),0);' – 2014-12-03 05:53:53

+1

@Praxeolitic我不認爲這是一個愚蠢的問題,通常當涉及到人們想要的副作用時[避免像瘟疫一樣的評估順序不明確](http://stackoverflow.com/q/27158812/1708801),因爲它通常會導致不好的事情。所以這個問題肯定需要精神上的飛躍。 – 2014-12-03 15:31:01

-1

那麼總是有一種明顯的方法來將指針指向容器中的函數,將其整理(或按照對其進行排序的建議),並調用容器中的每個項目。如果您需要每次運行都有相同的行爲,請確保您的種子每次都是相同的。

+0

@Mohit Jain你能詳細說明一下由同一個種子生成的隨機順序與未指定的不同麼?無論哪種情況,您都可以在單次運行程序後輕鬆確定訂單。 – 2014-12-03 05:02:42

+2

對容器進行排序也是可行的,因爲函數地址的排序是未指定的。 – 2014-12-03 05:09:44

+0

@BenjaminLindley不錯的逆轉!這個想法可能會使這個答案可行,但避免招致UBD?函數指針比較合法嗎? – Praxeolitic 2014-12-03 05:36:24