Побитовое или гарантирование оценки заказа?

Скажем, у меня есть этот код:

unsigned int func1();
unsigned int func2();
unsigned int func3();

unsigned int x = func1() | func2() | func3();

Гарантирует ли С++, что func1() будет вызываться первым, затем func2(), а затем func3()?

Или компилятор разрешен для вызова функций в любом порядке, в котором он выглядит?

Кроме того, компилятор разрешил реализовать оптимизацию короткого замыкания здесь, если он хочет? (например, если func1() возвращен ~ 0, может ли компилятор решить не беспокоить вызовы func2() или func3(), потому что он знает, что их возвращаемые значения не могут повлиять на значение, присвоенное x?)

Ответы

Ответ 1

Нет, нет гарантии, какой порядок вызовут функции. В отличие от ||, | не подразумевает точку последовательности.

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

Ответ 2

Это не будет короткое замыкание. Он может выполняться не в порядке.

"Направление оценки не влияет на результаты выражений, которые включают в себя более одного умножения (*), сложения (+) или двоично-побитового (& | ^) оператора на одном уровне".