Постинкрементный аргумент функции при вызове функции - PullRequest
0 голосов
/ 27 марта 2020
 m=3;
function(m++);

Какой параметр будет передан 3 или 4? Я читал, что в постинкрементном значении изменения после завершения оператора (точка с запятой достигнута), но нет точки с запятой, поэтому значение не изменится и останется 3?

Ответы [ 5 ]

2 голосов
/ 28 марта 2020

Выражение m++ имеет результат и побочный эффект .

Результат из m++ является текущим значением m (3) - это то, что передается в качестве аргумента функции. Побочный эффект заключается в том, что 1 добавляется к m.

Это примерно эквивалентно записи

function( m );
m += 1;

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

Аналогично, результатом выражения ++m является значение m плюс 1, и побочным эффектом является то, что 1 добавляется к m, поэтому, если вы передали ++m в качестве аргумента функции функция получит значение 4.

Опять же, это примерно эквивалентно

function( m + 1 );
m += 1;

с тем же предостережением, что и выше, когда обновляется m.

2 голосов
/ 27 марта 2020

Оператор

function(m++);

по существу эквивалентен

{
    type_of_m compiler_generated_temporary_variable = m;
    m = m + 1;
    function(compiler_generated_temporary_variable);  // Passes the old value of m
}

Так что m будет увеличено после завершения полного выражения, но его старое значение будет передано function.

1 голос
/ 27 марта 2020

Какой параметр будет передан 3 или 4?

Стандарт C в основном говорит о двух вещах о m++:

  • Значение это выражение является значением m перед выполнением любого приращения.
  • В качестве побочного эффекта сохраненное значение m увеличивается на 1.

Я читал, что в постинкрементном значении изменения после завершения оператора (точка с запятой достигнута)

Это неверно. Стандарт C не указывает c об изменении сохраненного значения. Может измениться до значения этого выражения (но используемое значение все равно будет прежним значением m, даже если компилятор должен сохранить это значение в каком-то временном месте, чтобы запомнить его) , он может изменить после значения или даже во время использования значения.

Стандарт C имеет некоторые правила по этому поводу , Во-первых, все побочные эффекты завершаются до следующей точки последовательности. Другая причина заключается в том, что после оценки каждого полного выражения существует точка последовательности, которая включает все выражение в выражении . (Выражение-выражение - это выражение, за которым следует точка с запятой.) Поэтому приращение m произойдет до , оператор завершен, а не после и не обязательно просто до это завершается, но это может происходить в разное время во время оператора.

Другое правило, которое стандарт C имеет относительно побочных эффектов, состоит в том, что после оценки аргументов функции есть точка последовательности звонить и до фактического звонка. Итак, в m=3; function(m++); переданное значение равно 3, m изменяется на 4, и вызывается function, и, кроме того, изменение m на 4 должно быть завершено до вызова function .

0 голосов
/ 27 марта 2020

Давайте посмотрим на инструкции, сгенерированные G CC для следующего фрагмента кода

int main(void) {

    int x;

    x = 5;

    func(x++);

    return(0);
}

-

main:
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $16, %rsp
        movl    $5, -4(%rbp)       ; 5 gets stored
        movl    -4(%rbp), %eax     ; moves the value 5 into %eax register
        leal    1(%rax), %edx      ; %edx contains the value 6
        movl    %edx, -4(%rbp)     ; moves the value 6 into x
        movl    %eax, %edi         ; moves the value of %eax, which is 5, into %edi for the function to use
        call    func
        movl    $0, %eax
        leave
        ret

Обратите внимание, что значение 6 и значение 5 находятся в разных регистрах.

0 голосов
/ 27 марта 2020

Это постинкремент, означающий, что он будет увеличивать ПОСЛЕ того, как выражение завершится.

m++

Это предварительное увеличение, то есть оно будет увеличиваться ДО того, как выражение будет выполнено.

++m

Таким образом, в вашем случае использования, он пройдет 3, а не 4.

...