2014-12-03 2 views
8

Есть ли способ в C и C++ вызвать функции, возвращающие 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++, составленного конформным компилятор может распечатать hi, bye и moo в любом порядке. Это не неопределенное поведение (nasal demons недействительно), существует просто более одного, но менее бесконечного допустимых выходов, а совместимый компилятор не должен даже быть детерминированным в том, что он производит.

Есть ли способ сделать это без возвращаемых значений фиктивных данных?

Уточнение: Это абстрактный вопрос о C и C++. Возможно, лучше исходная фразировка была в каком-либо контексте, в котором порядок оценки функции не указан для функций, возвращающих void? Я не пытаюсь решить конкретную проблему.

+0

Если методы 'void' почему бы вы использовать их в качестве параметр? – John3136

+0

Моя цель - не использовать их в качестве параметра, а оценивать их в неуказанном порядке. – Praxeolitic

+0

@Gyapti прецедент любопытство. – Praxeolitic

ответ

9

Вы можете воспользоваться тем фактом, что левая сторона руки оператора запятой выражение отбрасывает значения (недействительное выражение в C), как это (see it live):

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

От проект с ++ стандартный раздел 5.18оператор Разделенный:

пара выражений, разделенных запятая оценивается слева направо; левое выражение является выражением отбрасываемого значения (раздел 5).

и секции С11 6.5.17Разделенный оператор:

Левый операнд оператора запятой оценивается как выражение недействительным; есть точка последовательности между ее оценкой и правилом операнда. Затем оценивается правый операнд ; результат имеет свой тип и значение.

Как Мэтт указывает это также можно смешивать выше метод с арифметическими операторами для достижения энное порядка оценки:

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

Мне понравился этот ответ. Некоторые из наиболее интересных вещей, которые я узнал о SO, вызваны противоречивыми вопросами, которые кажутся глупыми для некоторых. – Praxeolitic

+2

Вам вообще не нужно «фиктивный», так как порядок оценки других операторов также не указан; например '(hi(), 0) + (bye(), 0) + (moo(), 0);' –

+1

@Praxeolitic Я не думаю, что это глупый вопрос, обычно когда дело доходит до побочных эффектов, которые люди хотят [избегать неопределенного порядка оценки, такого как чума] (http://stackoverflow.com/q/27158812/1708801), потому что это обычно приводит к плохим вещам. Поэтому этот вопрос определенно требует умственного скачка. –

-1

Ну, всегда есть очевидный подход, заключающийся в том, чтобы накладывать указатели на функции в контейнере, перетасовывать его (или, как предложено в сортировке комментариев), и вызывать каждый элемент в контейнере. Если вам нужно иметь одно и то же поведение, каждый из них запускается, убедитесь, что каждое семя будет одинаковым.

+0

@Mohit Jain Можете ли вы рассказать о том, как случайный порядок, создаваемый одним и тем же семенем, отличается от неуказанного? В любом случае вы можете легко определить порядок после одного прогона программы. –

+2

Сортировка контейнера также будет работать, поскольку порядок адресов функций не указан. –

+0

@BenjaminLindley Хороший поворот! Эта идея может сделать этот ответ жизнеспособным, но не позволяет ли он принимать UBD? Является ли сравнение указателей на функции указателем? – Praxeolitic

Смежные вопросы