Я думаю, ответ @MSalters очень хорошо решил мой вопрос. Но я хочу больше поговорить о x = 1 + x
в Python и C / C ++.
TL; DR
В обоих C / C ++ и Python, если есть глобальная переменная x
и оператор (int) x = 1 + x
в функции. Python сообщит об ошибке, как я написал в вопросе, C / C ++ должен быть НЕ УКАЗАН. Фактически, причина, по которой она НЕ УКАЗАНА в C / C ++, такая же, как у Python: используйте локальную переменную x
перед присваиванием.
Подробно о том, почему она НЕПРАВИЛЬНА (НЕ УКАЗАНА) в C / C ++ тоже.
#include <stdio.h>
int x = 1;
int main()
{
int x = 1 + x; // Here compiler know we take not only first x as a local variable but also the second. It means first and second x point to same memory.
printf("%d\n", x); // print 1.
return 0;
}
, поскольку clang
жалуется: [clangtidy] The right operand of '+' is a garbage value [clang-analyzer-core.UndefinedBinaryOperatorResult] [W]
.
Соответствующий код сборки:
x:
.long 1
.section .rodata
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
addl $1, -4(%rbp) // 1 + local x, if use global x it should be: movl x(%rip), %eax THEN: addl $1, %eax
movl -4(%rbp), %eax // use result of 1 + local x as print's arg
movl %eax, %esi
leaq .LC0(%rip), %rdi
movl $0, %eax
call printf@PLT
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 9.2.0"
.section .note.GNU-stack,"",@progbits
Это показывает, что мы никогда не используем глобальный x
. И почему компилятор не использует глобальный x
, возможно, не заслуживает этого, поскольку это неправильный / запутанный стиль написания.
Так что в C / C ++ компилятор знает, что весь код ниже ссылается на новую переменную в этом область видимости, когда компилятор видит variable declaration
, вроде int x = 1 + x;
. Это глобальная переменная, если нет variable declaration
, как x = 1 + x
в функции.
Но в python интерпретатор был сбит с толку, когда x += 1
или x = 1 + x
были прочитаны, как @MSalters 's ответ сказал python нет variable declaration
. Python принятие присваивания ссылается на переменную в текущей области видимости, чтобы сделать ее более точной c, иначе интерпретатор должен отслеживать цепочку вызовов, чтобы найти переменную (или просто найти ее в глобальной области видимости), тогда будет плохо, если вы захотите объявить переменная как x
в текущей области видимости.