대입 연산자가 값을 반환하면 어떤 이점이 있습니까?


27

Javascript와 PHP를 모두 대체하려는 언어를 개발 중입니다. (나는 이것에 어떤 문제도 보이지 않는다.이 언어들 중 어느 것이 큰 설치 기반을 가지고 있지는 않다.)

내가 변경하고 싶었던 것 중 하나는 할당 연산자를 할당 명령으로 바꾸어 반환 값을 사용하는 기능을 제거하는 것이 었습니다.

x=1;          /* Assignment. */
if (x==1) {}  /* Comparison. */
x==1;         /* Error or warning, I've not decided yet. */
if (x=1) {}   /* Error. */

나는 이것이 C 사람들이 너무 좋아하는 단선 기능이 더 이상 작동하지 않음을 의미한다는 것을 알고 있습니다. 나는 이것이 대부분의 시간이 일어 났을 때 (개인 경험을 넘어서는 증거가 거의 없음) 실제로 비교 작업이 될 것이라고 생각했습니다.

아니면? 사소하게 다시 쓸 수없는 할당 연산자의 반환 값을 실제로 사용하고 있습니까? (이러한 개념을 가진 모든 언어의 경우)


12
JS와 PHP에 큰 "설치 기반"이 없습니까?
mhr

47
@mri 나는 풍자 의심합니다.
Andy Hunt

12
내가 기억할 수있는 유일한 유용한 사례는 while((x = getValue()) != null) {}입니다. 과제를 사용 break하거나 반복 해야하므로 교체가 더 어려워 x = getValue집니다.
코드 InChaos

12
@mri Ooh 아니오, 그 두 언어는 별다른 투자없이 사소한 일이라고 들었습니다. JS 사용을 주장하는 소수의 사람들이 내 언어를 본 후에는 내 언어로 전환하여 다시 ===를 쓰지 않아도됩니다. 브라우저 제조업체가 JS와 함께 내 언어가 포함 된 업데이트를 즉시 출시 할 것이라고 확신합니다. :)
billpg

4
기존 언어 를 향상 시키려는 의도가 있고 언어를 광범위하게 채택하려는 경우 기존 언어와 100 % 이전 버전과의 호환성이 좋습니다. 예를 들어 TypeScript를 참조하십시오. 기존 언어에 대한 더 나은 대안 을 제공하려는 의도라면 훨씬 어려운 문제가 있습니다. 새로운 언어는 전환 비용을 지불하기 위해 기존 언어보다 훨씬 현실적인 기존 문제를 해결 해야합니다. 언어를 배우는 것은 투자 이며 돈을 지불해야합니다.
Eric Lippert

답변:


25

기술적으로, 일부 구문 설탕은 일반적인 조작의 가독성을 향상 시키면 사소하게 교체 될 수 있어도 가치가 있습니다. 그러나 표현으로서의 할당은 그에 해당하지 않습니다. 비교 대신 입력 할 위험은 거의 사용되지 않으며 (스타일 가이드에 의해 금지되는 경우도 있음) 사용 시마다 이중 테이크를 유발합니다. 다시 말해서, 가독성 이점은 수와 크기가 작다.

이를 수행하는 기존 언어를 살펴 보는 것이 좋습니다.

  • Java와 C #은 표현식을 할당하지만 부울로 평가하기위한 조건을 요구하여 언급 한 함정을 제거합니다. 사람들은 때때로 이것이 if (x)대신에 if (x != null)또는 if (x != 0)유형에 따라 같은 조건을 허용하지 않는다고 불평하지만, 이것은 대부분 잘 작동하는 것 같습니다 x.
  • 파이썬은 대입을 표현식 대신 적절한 문장으로 만듭니다. 이 변경 제안은 때때로 파이썬 아이디어 메일 링리스트에 도달하지만, 주관적인 인상은 do-while 루프, 스위치 문, 다중 라인 람다, 기타

그러나 파이썬은 한 번에 여러 이름을 할당하는 특별한 경우를 허용 a = b = c합니다. 이것은와 동등한 문장으로 간주되며 b = c; a = b때때로 사용되므로 언어에 추가 할 가치가 있습니다 (그러나이 추가 기능은 이전 버전과 호환되어야하므로 땀을 흘리지 않습니다).


5
a = b = c다른 답변이 실제로 일어나지 않는 것을 기르기 위해 +1 .
Leo

6
세 번째 해결 방법은 할당에 다른 기호를 사용하는 것입니다. 파스칼은 :=할당에 사용 합니다.
Brian

5
@Brian : C #도 마찬가지입니다. =할당, ==비교입니다.
Marjan Venema 2014

3
C #에서, 같은 것을 if (a = true)던져 것 C4706의 경고를 ( The test value in a conditional expression was the result of an assignment.). C를 가진 GCC도 마찬가지로을 던질 것이다 warning: suggest parentheses around assignment used as truth value [-Wparentheses]. 이러한 경고는 추가 괄호를 사용하여 침묵시킬 수 있지만 과제가 의도적으로 있음을 명시 적으로 표시하도록 권장합니다.
Bob

2
@delnan 그냥 다소 일반적인 의견이지만 "는 논리 값으로 평가하는 조건을 요구하여 언급 함정 제거"에 의해 촉발되었다 - a = true 않는 부울로 평가를하기 때문에 오류가 아닙니다, 그러나 그것은 또한 C #에서 관련 경고를 발생시킵니다.
Bob

11

사소하게 다시 쓸 수없는 할당 연산자의 반환 값을 실제로 사용하고 있습니까?

일반적으로 말해서 대입 표현식의 값을 대입 한 값이라는 아이디어는 부작용 과 그 모두에 사용될 수 있고 많은 사람들이 혼동하는 것으로 간주되는 식을 의미합니다.

일반적인 사용법은 일반적으로 표현을 간결하게 만드는 것입니다.

x = y = z;

C #에서 "z를 y 유형으로 변환, 변환 된 값을 y로 할당, 변환 된 값은 표현식의 값, x 유형으로 변환, x에 할당"의 의미를 갖습니다.

그러나 우리는 이미 성명서 맥락에서 명령적인 부작용의 영역에 있으므로, 그에 대한 이점은 거의 없습니다.

y = z;
x = y;

마찬가지로

M(x = 123);

속기

x = 123;
M(x);

다시 한 번, 원래 코드에서 부작용과 값에 모두 표현식을 사용하고 있으며 하나 대신 두 가지 부작용이있는 명령문을 작성하고 있습니다. 둘 다 냄새가 난다. 명령문마다 하나의 부작용이 있고 부작용이 아닌 값에 표현식을 사용하십시오.

Javascript와 PHP를 모두 대체하려는 언어를 개발 중입니다.

대담하게하고 싶고 과제가 평등이 아니라 진술이라고 강조하고 싶다면, 나의 충고는 다음과 같습니다 . 분명히 그것을 분명히 진술하십시오 .

let x be 1;

빨간 것. 또는

x <-- 1;

또는 더 나은 :

1 --> x;

아니면 더 나은

1 → x;

어떤 것과 혼동 될 방법은 절대 없습니다 x == 1.


1
프로그래밍 언어에서 비 ASCII 유니 코드 기호를 사용할 준비가 되었습니까?
billpg

내가 제안한 것을 좋아하는 한, 나의 목표 중 하나는 대부분의 "잘 작성된"JavaScript를 거의 또는 전혀 수정하지 않고 이식 할 수 있다는 것입니다.
billpg

2
@billpg : 세상은 준비 되었습니까? 모르겠다-유니 코드가 발명되기 수십 년 전인 1964 년에 APL에 대한 세계가 준비 되었는가? APL에는 처음 40 개 중 6 개의 숫자를 무작위로 바꾸는 프로그램이 있습니다. x[⍋x←6?40] APL에는 자체 특수 키보드가 필요했지만 꽤 성공적인 언어였습니다.
Eric Lippert

@billpg : Macintosh Programmer 's Workshop은 정규식 태그 또는 stderr 리디렉션과 같은 작업에 ASCII가 아닌 기호를 사용했습니다. 반면 MPW는 Macintosh에서 ASCII가 아닌 문자를 쉽게 입력 할 수 있다는 이점이있었습니다. 미국 키보드 드라이버가 ASCII가 아닌 문자를 입력하는 데 적절한 수단을 제공하지 않는 이유에 대해 의문을 제기해야합니다. Alt- 번호를 입력하면 문자 코드를 조회해야 할뿐만 아니라 많은 응용 프로그램에서도 작동하지 않습니다.
supercat

흠, 왜 "오른쪽에"를 할당하는 것을 선호 a+b*c --> x합니까? 나에게 이상해 보인다.
Ruslan

9

많은 언어는 파이썬을 포함하여 표현식이 아닌 명령문을 지정하는 경로를 선택합니다.

foo = 42 # works
if foo = 42: print "hi" # dies
bar(foo = 42) # keyword arg

그리고 Golang :

var foo int
foo = 42 # works
if foo = 42 { fmt.Printn("hi") } # dies

다른 언어에는 할당이 없지만 범위가 지정된 바인딩 (예 : OCaml)이 있습니다.

let foo = 42 in
  if foo = 42 then
    print_string "hi"

그러나 let표현 자체입니다.

할당을 허용하는 이점은 조건부 내부에서 함수의 반환 값을 직접 확인할 수 있다는 것입니다 (예 :이 Perl 스 니펫).

if (my $result = some_computation()) {
  say "We succeeded, and the result is $result";
}
else {
  warn "Failed with $result";
}

Perl은 선언을 해당 조건부로만 범위를 지정하므로 매우 유용합니다. 또한 새 변수를 선언하지 않고 조건부 내부에 할당 if ($foo = $bar)하면 경고 if (my $foo = $bar)합니다.

다른 문장으로 과제를 작성하면 충분하지만 범위 지정 문제가 발생할 수 있습니다.

my $result = some_computation()
if ($result) {
  say "We succeeded, and the result is $result";
}
else {
  warn "Failed with $result";
}
# $result is still visible here - eek!

Golang은 오류 검사를 위해 반환 값에 크게 의존합니다. 따라서 조건부에서 초기화 명령문을 취할 수 있습니다.

if result, err := some_computation(); err != nil {
  fmt.Printf("Failed with %d", result)
}
fmt.Printf("We succeeded, and the result is %d\n", result)

다른 언어는 유형 시스템을 사용하여 조건부 내에서 부울이 아닌 표현식을 허용하지 않습니다.

int foo;
if (foo = bar()) // Java does not like this

물론 부울을 반환하는 함수를 사용할 때 실패합니다.

우연히 할당을 방지하기 위해 다른 메커니즘을 보았습니다.

  • 식으로 할당을 허용하지 않음
  • 정적 유형 검사 사용
  • 과제가 존재하지 않으며 let바인딩 만 있습니다.
  • 초기화 문장을 허용하고 그렇지 않으면 할당을 허용하지 않습니다
  • 선언없이 조건부 내에서 할당을 허용하지 않습니다.

나는 선호하는 오름차순으로 순위를 매겼습니다. 표현식 내부의 할당은 유용 할 수 있습니다 (명시 적 선언 구문과 다른 명명 된 인수 구문을 사용하여 Python의 문제를 피하는 것이 간단합니다). 그러나 동일한 효과에 대한 다른 많은 옵션이 있으므로 허용하지 않는 것이 좋습니다.

버그가없는 코드는 간결한 코드보다 중요합니다.


"표현식으로 할당 허용 안 함"+1 식으로 할당을위한 사용 사례는 버그 및 가독성 문제의 가능성을 정당화하지 않습니다.
찌르다

7

당신은 "내 개인적인 경험을 넘어서는 거의 증거가 거의 없다"고 말했다.

왜 문제를 해결하지 않습니까?

대입을 위해 =와 등식 테스트를 위해 == 대신에 대입을 위해 : =를 사용하고 동등성을 위해 = (또는 ==)를 사용하지 않는 이유는 무엇입니까?

관찰 :

if (a=foo(bar)) {}  // obviously equality
if (a := foo(bar)) { do something with a } // obviously assignment

프로그래머가 할당을 평등하게 착각하는 것을 더 어렵게하려면 더 어렵게 만드십시오.

동시에, 만약 당신이 정말로 문제를 고치려고한다면, 불리언은 단지 사전 정의 된 상징적 설탕 이름을 가진 정수라고 주장하는 C crock을 제거 할 것입니다. 그것들을 모두 다른 유형으로 만드십시오. 그런 다음 말하는 대신

int a = some_value();
if (a) {}

프로그래머는 다음과 같이 작성해야합니다.

int a = some_value();
if (a /= 0) {} // Note that /= means 'not equal'.  This is your Ada lesson for today.

사실 운영자로서의 할당은 매우 유용한 구조입니다. 우리는 일부 사람들이 스스로 자르기 때문에 면도날을 제거하지 않았습니다. 대신 질레트 왕은 안전 면도기를 발명했습니다.


2
(1) :=할당과 =평등을 위해이 문제를 해결할 수는 있지만 작은 비 주류 언어를 사용하여 자라지 않은 모든 프로그래머를 소외시키는 비용이 발생합니다. (2) 조건에서 허용되는 bool 이외의 유형이 항상 bool과 정수를 혼합 한 것이 아니기 때문에 다른 유형에 대한 참 / 거짓 해석을하기에 충분합니다. C를 벗어나는 것을 두려워하지 않는 최신 언어는 정수 이외의 많은 유형에 대해 그렇게했습니다 (예 : Python은 빈 컬렉션을 거짓으로 간주합니다).

1
면도날과 관련하여 : 선명도를 필요로하는 사용 사례를 제공합니다. 반면에, 나는 프로그래밍 평가가 식 평가의 중간에 변수를 할당해야한다고 확신하지 않습니다. 가장자리가 날카롭지 않고 체모를 사라지게하는 간단하고 기술이 안전하며 비용 효율적인 방법이 있다면 면도날이 변위되거나 적어도 훨씬 더 희귀 해졌을 것입니다.

1
@delnan : 한 현명한 사람이 한 번 말했다. "가급적 단순하지만 단순하게 만드십시오." 목표가 대부분의 a = b 대 a == b 오류를 제거하는 것이라면 조건부 테스트 영역을 부울로 제한하고 <other>-> boolean에 대한 기본 유형 변환 규칙을 제거하면 거의 모든 것을 얻을 수 있습니다. 그곳에. 이때 a와 b가 모두 부울이고 a가 유효한 lvalue 인 경우 if (a = b) {}는 구문 상으로 만 유효합니다.
John R. Strohm

틀림없이 - 할당을 만들기 성명은 간단 적어도이다 더 간단 이상 -를 사용해서 제안 변경하고 달성 한 적어도만큼 - 틀림없이 더 (도 허용하지 않는 if (a = b)A, 부울 A, B 좌변에 대한). 정적 타이핑이없는 언어에서는 구문 분석 시간과 실행 시간보다 훨씬 더 나은 오류 메시지를 제공합니다. 또한 "a = b vs. a == b 오류"를 방지하는 것이 유일한 관련 목표는 아닙니다. 예를 들어, 나는 또한 같은 허가 코드 싶습니다 if items:의미하는 if len(items) != 0, 나는 논리 값에 대한 조건을 제한하기 위해 포기해야 거라고.

1
@delnan Pascal은 주류가 아닌 언어입니까? 수백만의 사람들이 Pascal (및 / 또는 Pascal에서 파생 된 Modula)을 사용하여 프로그래밍을 배웠습니다. 그리고 델파이는 여전히 많은 국가에서 일반적으로 사용됩니다 (귀하의 국가에서는 그리 많지 않을 수도 있습니다).
jwenting

5

실제로 질문에 대답하기 위해, 틈새 시장이지만 약간의 용도가 있습니다.

예를 들어 Java의 경우 :

while ((Object ob = x.next()) != null) {
    // This will loop through calling next() until it returns null
    // The value of the returned object is available as ob within the loop
}

임베디드 할당을 사용하지 않는 대안 ob은 루프 범위 외부 에 정의 된 x.next ()를 호출하는 두 개의 개별 코드 위치가 필요합니다.

한 번에 여러 변수를 할당 할 수 있다고 이미 언급했습니다.

x = y = z = 3;

이런 종류의 것이 가장 일반적으로 사용되지만 창조적 인 프로그래머는 항상 더 많은 것을 생각 해낼 것입니다.


루프 조건이 할당 해제되고 ob모든 루프마다 새 객체가 생성 됩니까?
user3932000

@ user3932000이 경우에는 아마도 x.next ()가 무언가를 반복하고있을 것입니다. 그래도 가능할 것입니다.
Tim B

1

모든 규칙을 구성하기 때문에 할당에서 값을 설정 하도록 허용 하고 조건부 단계 내에서 할당을 허용 하지 않는 이유 는 무엇입니까? 이것은 일반적인 코딩 실수를 방지하면서 초기화를 쉽게 해주는 구문 설탕을 제공합니다.

다시 말해, 이것을 합법적으로 만드십시오 :

a=b=c=0;

그러나 이것을 불법으로 만드십시오 :

if (a=b) ...

2
그것은 다소 임시 규칙처럼 보입니다. 할당 문을 작성하고 확장하여 a = b = c더 직교적이고 구현하기도 쉽다. 이 두 가지 접근법은 표현식 ( a + (b = c)) 에서의 대입에 대해 동의하지 않지만, 당신은 그 점을 고려하지 않았으므로 그것들은 중요하지 않다고 가정합니다.

"구현하기 쉽다"는 고려할 필요가 없습니다. 사용자 인터페이스를 정의하고 있으며 사용자의 요구를 최우선으로 생각합니다. 이 동작이 사용자에게 도움이되는지 또는 방해가되는지 스스로에게 묻기 만하면됩니다.
Bryan Oakley

부울로의 암시 적 변환을 허용하지 않으면 조건에서 할당에 대해 걱정할 필요가 없습니다
ratchet freak

구현하기 쉬운 것은 나의 주장 중 하나 일뿐입니다. 나머지는 어떻습니까? UI 측면에서 IMHO의 일관성없는 디자인 및 임시 예외는 일반적으로 사용자가 규칙을 파악하고 내재화하는 데 방해가된다고 덧붙일 수 있습니다.

@ratchetfreak 당신은 여전히 ​​실제 부울을 할당하는 데 문제가있을 수 있습니다
jk.

0

그것의 소리에 의해, 당신은 상당히 엄격한 언어를 창조하는 길에 있습니다.

이를 염두에두고 사람들이 다음과 같이 작성하도록합니다.

a=c;
b=c;

대신에:

a=b=c;

사람들이 행동하지 못하도록 개선 된 것처럼 보일 수 있습니다.

if (a=b) {

그들이 할 때 :

if (a==b) {

그러나 결국 이런 종류의 오류는 쉽게 감지 할 수 있고 이들이 합법적 인 코드인지 여부에 대해 경고합니다.

그러나 다음과 같은 상황이 있습니다.

a=c;
b=c;

그 의미는 아닙니다

if (a==b) {

사실입니다.

c가 실제로 함수 c ()이면 호출 될 때마다 다른 결과를 반환 할 수 있습니다. (또한 계산 비용이 많이들 수 있습니다 ...)

마찬가지로 c가 메모리 매핑 된 하드웨어에 대한 포인터 인 경우

a=*c;
b=*c;

둘 다 다를 가능성이 높으며, 또한 읽을 때마다 하드웨어에 전자적 영향을 미칠 수 있습니다.

하드웨어에 대해서는 다른 타이밍 순열이없이 동일한 라인에서 여러 할당을 빠르고 간단하고 명백하게하는 메모리 주소를 읽고, 특정 타이밍 제약 조건에서 읽고 쓰는 것에 대해 정밀해야하는 다른 많은 순열이 있습니다. 임시 변수 소개


4
동등한에이 a = b = c아니다 a = c; b = c, 그것은이다 b = c; a = b. 이 피한 부작용 중복도의 수정 유지 ab같은 순서로한다. 또한 이러한 모든 하드웨어 관련 주장은 어리석은 것입니다. 대부분의 언어는 시스템 언어가 아니며 이러한 문제를 해결하도록 설계되지 않았으며 이러한 문제가 발생하는 상황에서도 사용되지 않습니다. 이것은 JavaScript 및 / 또는 PHP를 대체하려는 언어의 경우 두 배가됩니다.

델난, 문제는 이러한 예가 아니라는 것입니다. 요점은 여전히 ​​a = b = c를 쓰는 것이 일반적이며 하드웨어의 경우 OP가 요청 한대로 모범 사례로 간주되는 장소의 종류를 보여줍니다. 그들이 기대 한 환경과의 관련성을 고려할 수있을 것이라고 확신합니다
Michael Shaw

되돌아 보면,이 답변에 대한 나의 문제는 주로 시스템 프로그래밍 사용 사례에 중점을 두는 것이 아니라 (충분히 좋지는 않지만 작성된 방식) 잘못된 재 작성을 가정하는 것입니다. 예 a=b=c는 일반적 / 유용한 장소의 예가 아니며 , 순서와 부작용의 수를 처리해야하는 장소의 예입니다. 그것은 전적으로 독립적입니다. 체인 할당을 올바르게 다시 작성하면 두 변형이 모두 동일합니다.

@delnan : rvalue는 b한 temp의 유형으로 변환 a되고 다른 temp 의 유형으로 변환됩니다 . 해당 값이 실제로 저장되는 시점의 상대적 타이밍은 지정되지 않습니다. 언어 설계 관점에서 볼 때, 다중 할당 문의 모든 lvalue가 일치하는 유형을 요구하고 휘발성이없는 것도 요구하는 것이 합리적이라고 생각합니다.
supercat

0

과제가 표현이라는 나의 마음에 가장 큰 이점은 당신의 목표 중 하나가 "모든 것이 표현이다"-특히 LISP의 목표라면 문법이 더 단순해질 수 있다는 것입니다.

파이썬은 이것을 가지고 있지 않습니다. 그것은 표현과 진술을 가지고 있으며, 과제는 진술이다. 그러나 파이썬은 lambda폼을 하나의 매개 변수 으로 정의하기 때문에 람다 안에 변수를 할당 할 수 없습니다. 이것은 때때로 불편하지만 중요한 문제는 아니며 내 경험에서 유일하게 파이썬에서 과제를 진술하는 단점이 있습니다.

if(x=1)C가 가진 사고 의 가능성을 유발 하지 않고 과제 또는 과제의 영향을 표현으로 표현할 수있는 한 가지 방법 은 귀하의 언어에서로 평가 될 수 있는 LISP와 유사한 let구조 를 사용하는 (let ((x 2) (y 3)) (+ x y))5입니다. 어휘 범위를 만드는 것으로 let정의한 경우이 방법을 사용 하면 기술적으로 언어로 할당 할 필요가 없습니다 let. 이런 식으로 정의하면 let구문을 사용하여 중첩 된 클로저 함수를 생성하고 호출하는 것과 같은 방식으로 구문을 컴파일 할 수 있습니다.

반면에, 단순히 if(x=1)사건에 관심이 있지만 C에서와 같이 표현이되기를 원한다면 다른 토큰을 선택하면 충분할 것입니다. 과제 : x := 1또는 x <- 1. 비교 : x == 1. 구문 오류 : x = 1.


1
let새로운 범위에서 새로운 변수를 기술적으로 도입하는 것보다 더 많은 방식으로 할당과 다릅니다. 우선, let본문 외부의 코드에는 영향을 미치지 않으므로 할당이 많은 코드의 중요한 단점 인 변수를 사용해야하는 모든 코드를 더 중첩해야합니다. 이 경로를 따라 내려 가면 set!비교와 완전히 다르지만 중첩이나 새로운 범위가 필요없는 Lisp 아날로그가 더 좋습니다.

@delnan : (1) 재 선언이 선언 및 할당 식별자에만 유효하다는 규칙에 따라 재 할당을 금지하지만 재 선언을 허용하는 조합 선언 및 할당 구문을보고 싶습니다. ) 재 선언은 모든 포함 범위에서 변수를 "선언"합니다. 따라서 유효한 식별자의 값은 해당 이름의 이전 선언에 지정된 값입니다. 그것은 몇 줄에만 사용되는 변수에 대해 범위 지정 블록을 추가하거나 각 임시 변수에 대해 새 이름을 공식화하는 것보다 조금 더 좋을 것입니다.
supercat

0

나는 이것이 C 사람들이 너무 좋아하는 단선 기능이 더 이상 작동하지 않음을 의미한다는 것을 알고 있습니다. 나는 이것이 대부분의 시간이 일어 났을 때 (개인 경험을 넘어서는 증거가 거의 없음) 실제로 비교 작업이 될 것이라고 생각했습니다.

과연. 이것은 새로운 것이 아니며, C 언어의 모든 안전한 부분 집합은 이미이 결론을 내 렸습니다.

MISRA-C, CERT-C 등은 단순히 위험하기 때문에 모든 조건 내에서 배정을 금지합니다.

내부 조건 할당에 의존하는 코드를 다시 작성할 수없는 경우는 없습니다.


또한 이러한 표준은 평가 순서에 의존하는 코드 작성에 대해 경고합니다. 하나의 단일 행에 여러 할당 x=y=z;이 그러한 경우입니다. 여러 할당이있는 행에 부작용 (함수 호출, 변동 변수 액세스 등)이 포함 된 경우 어떤 부작용이 먼저 발생하는지 알 수 없습니다.

피연산자 평가 사이에는 시퀀스 포인트가 없습니다. 따라서 하위 표현식 y이 이전 또는 이후에 평가 되는지 여부를 알 수 없습니다 z. C에서 지정되지 않은 동작입니다. 따라서 이러한 코드는 언급 된 C의 안전한 하위 집합에 대해 잠재적으로 신뢰할 수없고, 이식 가능하지 않으며 적합하지 않습니다.

해결책은 코드를로 대체하는 것입니다 y=z; x=y;. 이것은 시퀀스 포인트를 추가하고 평가 순서를 보장합니다.


따라서 C에서 발생하는 모든 문제를 바탕으로 현대 언어는 조건 내 할당을 금지하고 단일 행에 여러 할당을 금지하는 것이 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.