Нет гарантии относительно порядка, в котором оцениваются аргументы функции. Также нет точки последовательности между оценкой различных аргументов функции.
Это означает, что ваш первый вызов дает неопределенное поведение, потому что как использует существующее значение i
и записывает новое значение i
без точки последовательности между ними.
В типичном случае каждый аргумент функции будет оцениваться как отдельное выражение без перемежения между ними.Другими словами, компилятор будет налагать некоторый заказ на оценку, даже если стандарт не требует этого.
В конкретном случае вариационной функции аргументы обычно помещаются в стек справа налево, поэтому первый аргумент (строка формата) будет находиться в верхней части стека. Это облегчает поиск printf
строки формата, а затем (на основе этого) извлекает остальные аргументы из дальнейшего стека.
Если (как и довольно), то аргументы вычисляются непосредственно перед тем, как их вставлять в стек, это приведет к тому, что аргументы будут также оцениваться справа налево.
Функции с фиксированным числом аргументов не оцениваются справа налево почти так же часто, поэтому, если (например) вы написали небольшую обертку с фиксированным числом аргументов, которые затем передавали их до printf
, есть больше шансов, что i
будет иметь значение 55
, когда первый аргумент printf
вычисляется, так что будет производить 1 вместо 0.
Примечания, однако, что ни один результат гарантирован, ни любых смысла результат гарантирован - так как у вас есть неопределенное поведение, что-либо разрешено.
у вас есть операция назначения в первом printf !! .. вывод первого кода определяется реализацией. –