IT

왜 진술 (j ++)인가?

lottoking 2020. 5. 26. 07:57
반응형

왜 진술 (j ++)인가? 금지?


다음 코드가 잘못되었습니다 ( ideone 참조 ).

public class Test
{
    public static void Main()
    {
        int j = 5;
        (j++);      // if we remove the "(" and ")" then this compiles fine.
    }
}

오류 CS0201 : 할당, 호출, 증분, 감소, 대기 및 새 객체 표현식 만 명령문으로 사용할 수 있습니다.

  1. 괄호를 제거 할 때 코드가 컴파일되는 이유는 무엇입니까?
  2. 왜 괄호로 컴파일되지 않습니까?
  3. C #은 왜 그렇게 설계 되었습니까?

깊은 통찰력에 감사드립니다.

최선을 다하겠습니다.

다른 답변이 지적했듯이, 어떤 일이 일어나고 것은 컴파일러가 있음을 감지하는 것입니다 표현이 A와 사용되는 . C, JavaScript 및 기타 여러 언어에서 표현식을 명령문으로 사용하는 것은 합법적입니다. 2 + 2;효력이없는 진술 임에도 불구하고 이러한 언어에서는 합법적입니다. 일부 표현식은 해당 값에만 유용하고 일부 표현식은 부작용 (예 : void returning method 호출)에만 유용하며 일부 표현식은 불행히도 두 가지 모두에 유용합니다. (증가처럼)

요점 : 표현만으로 구성되는 진술은 그 표현이 일반적으로 값보다 부작용에 더 유용한 것으로 생각되지 않는 한 거의 확실하게 오류 입니다. C # 디자이너는 일반적으로 부작용으로 간주되는 표현을 허용하고 일반적으로 가치에 유용한 것으로 간주되는 표현은 허용하지 않음으로써 중간 지점을 찾고자했습니다. C # 1.0에서 식별 한 식 집합은 증분, 감소, 메서드 호출, 할당 및 다소 논쟁의 여지가있는 생성자 호출이었습니다.


ASIDE : 일반적으로 대상의 구성은 구성의 부작용이 아닌 생성 된 값에 사용되는 것으로 생각합니다. 내 생각에 허용 new Foo();은 약간의 오해입니다. 특히, 실제 패턴에서 보안 결함을 일으키는이 패턴을 보았습니다.

catch(FooException ex) { new BarException(ex); } 

코드가 복잡하면이 결함을 발견하기가 놀랍게 어려울 수 있습니다.


따라서 컴파일러는 해당 목록에없는 표현식으로 구성된 모든 명령문을 감지합니다. 특히 괄호로 묶인 표현식은 괄호로 묶인 표현식으로 식별됩니다. "문 표현으로 허용됨"목록에 없으므로 허용되지 않습니다.

이 모든 것은 C # 언어의 디자인 원칙을 따르고 있습니다. 당신이 타이핑 (x++);했다면 당신은 아마 뭔가 잘못했을 것 입니다. 이것은 아마도 오타 M(x++);일 수도 있습니다. C # 컴파일러 팀 의 태도는 " 이 작업을 수행 할 수있는 방법을 찾을 수 있는가? " 가 아니라는 점을 기억하십시오 . "C # 컴파일러 팀의 태도는" 유연한 코드가 실수 일 가능성이있는 경우 개발자에게 알려주십시오 "입니다. C # 개발자는 그런 태도를 좋아합니다.

이제 말했다 모두가 실제로는 C # 사양이 약간 이상한 경우가 있습니다 않습니다 의미 또는 괄호는 허용하지만 C # 컴파일러 어쨌든을 허용하는 명백한 것을 상태. 대부분의 경우 지정된 동작과 허용 된 동작 사이의 사소한 불일치는 완전히 무해하므로 컴파일러 작성자는 이러한 작은 버그를 수정 한 적이 없습니다. 당신은 그에 대해 읽을 수 있습니다 :

수익률 myVar와 수익률 (myVar)간에 차이가 있습니까?


에서 C # 언어 사양

식 문은 식을 평가하는 데 사용됩니다. 명령문으로 사용할 수있는 표현식에는 메소드 호출, 새 연산자를 사용한 오브젝트 할당, =를 사용한 지정 및 복합 지정 연산자, ++ 및-연산자를 사용한 증분 및 감소 조작 및 대기식이 포함됩니다.

명령문을 괄호로 묶으면 소위 괄호로 묶인 표현식이 새로 작성됩니다. 사양에서 :

괄호로 묶인 표현식은 괄호로 묶인 표현식으로 구성됩니다. ... 괄호 안에있는 표현식을 평가하여 괄호 안에있는 표현식을 평가합니다. 괄호 안의 표현식이 네임 스페이스 또는 유형을 나타내는 경우 컴파일 타임 오류가 발생합니다. 그렇지 않으면 괄호로 묶은 표현식의 결과는 포함 된 표현식의 평가 결과입니다.

괄호로 묶은 표현식은 유효한 표현식 명령문으로 나열되지 않으므로 스펙에 따라 올바른 명령문이 아닙니다. 디자이너가 그것을 할 선택한 이유이 방법은 누구의 추측이지만 전체 문을 괄호에 포함되는 경우 괄호 유용한 일을하지 않기 때문에 내 건은 다음과 같습니다 stmt(stmt)정확히 동일합니다.


beacause 주위의 괄호 i++는 표현식을 작성 / 정의하고 있습니다. 오류 메시지에서 알 수 있듯이 간단한 표현식은 명령문으로 사용할 수 없습니다.

왜 언어가 이런 식으로 설계 되었습니까? 코드처럼 오해를 일으키지 않는 문장으로 오해의 소지가있는 버그를 방지하기 위해

int j = 5;
j+1; 

두 번째 줄은 효과가 없습니다 (그러나 눈치 채지 못할 수도 있습니다). 그러나 컴파일러 대신 코드를 제거하는 대신 (코드가 필요하지 않기 때문에) 명시 적으로 코드를 제거하도록 요청하거나 무언가를 입력하지 않은 경우 수정해야합니다.

편집 :

c #의 대괄호 (캐스트 및 함수 호출과 같은 다른 용도 외에)는 표현식을 그룹화하고 단일 표현식 (하위 표현식 작성)을 리턴하는 데 사용됩니다.

그 코드 수준에서는 오직 stament 만 허용됩니다.

j++; is a valid statement because it produces side effects

근데 용감한 표현을 사용하면 표현으로 변합니다

myTempExpression = (j++)

myTempExpression;

컴파일러가 표현식을 부작용으로 확신 할 수 없기 때문에 유효하지 않습니다 (중지 문제가 발생하지 않는 한).

참고 URL : https://stackoverflow.com/questions/34422168/why-was-the-statement-j-forbidden

반응형