programing

왜 +++++B가 작동하지 않는가?

prostudy 2022. 5. 9. 21:59
반응형

왜 +++++B가 작동하지 않는가?

int main ()
{
   int a = 5,b = 2;
   printf("%d",a+++++b);
   return 0;
}

이 코드는 다음과 같은 오류를 제공한다.

오류: 증분 피연산자에 필요한 l값

하지만 만약 내가 모든 곳에 공간을 둔다면a++ +그리고++b그럼 잘 될 거야

int main ()
{
   int a = 5,b = 2;
   printf("%d",a++ + ++b);
   return 0;
}

첫 번째 예에서 오류가 의미하는 것은?

printf("%d",a+++++b);로 해석되다(a++)++ + b막시말 뭉크 규칙에! 따라

++는 (postfix) 가(postfix)에 평가되지 않는다.lvalue하지만 피연산자가 될 필요가 있다.lvalue.

! 6.4/4는 다음 사전 처리 토큰이 사전 처리 토큰을 구성할 수 있는 가장 긴 문자 시퀀스라고 말한다."

컴파일러는 단계별로 작성된다.첫 번째 단계는 렉서라고 불리며 캐릭터를 상징적인 구조로 바꾼다.그래서 "+"는 일종의 "+"와 같은 것이 된다.enum SYMBOL_PLUSPLUS파서 수 나중에 파서 단계는 이것을 추상 구문 트리로 바꾸지만 기호를 변경할 수는 없다.공백(따옴표에 없는 경우 기호가 끝나는 것)을 삽입하여 렉서에게 영향을 줄 수 있다.

일반 렉서들은 (일부 예외를 제외하고는) 욕심이 많아서 당신의 코드는 다음과 같이 해석되고 있다.

a++ ++ +b

파서 입력은 기호의 스트림이므로, 당신의 코드는 다음과 같다.

[ SYMBOL_NAME(name = "a"), 
  SYMBOL_PLUS_PLUS, 
  SYMBOL_PLUS_PLUS, 
  SYMBOL_PLUS, 
  SYMBOL_NAME(name = "b") 
]

파서가 구문론적으로 틀렸다고 생각하는 것. (주석을 바탕으로 한 EDIT:r-값에 ++를 적용할 수 없으므로 의미론적으로 부정확하며, 이 경우 a++)

a+++b 

이다

a++ +b

괜찮다.너의 다른 예들도 그렇다.

이 정확한 예는 C99 표준 초안(C11의 동일한 세부사항) 6.4 어휘소 요소 제4항에서 다루며, 이 초안은 다음과 같다.

입력 스트림을 지정된 문자까지 사전 처리 토큰으로 구문 분석했다면 다음 사전 처리 토큰은 사전 처리 토큰을 구성할 수 있는 가장 긴 문자 시퀀스다. [...]

모호함을 피하기 위해 어휘 분석에 사용되는 최대 뭉치 규칙이라고도 하며 유효한 토큰을 형성하기 위해 가능한 많은 요소를 취함으로써 작동한다.

단락은 또한 두 가지 예를 가지고 있다. 두 번째 예는 당신이 질문하는 것과 정확히 일치하며 다음과 같다.

예 2 프로그램 조각 x+++++++++++++++++로 구문 분석하는데, 구문 분석 x+++++++ y가 정확한 식을 산출할 수 있더라도 증분 연산자의 제약조건을 위반한다.

이는 우리에게 다음과 같은 것을 말해준다.

a+++++b

다음과 같이 구문 분석한다.

a ++ ++ + b

첫 번째 포스트 증분의 결과가 r값이고 포스트 증분의 결과가 l값을 요구하기 때문에 포스트 증분의 제약조건을 위반한다.이 내용은 섹션에 설명되어 있다.6.5.2.4 ( 것 강조)라고 말하는 사후 처리 증가 감소 연산자:

사후 처리 증감 운영자의 피연산자는 적격 또는 부적격의 실제 또는 포인터 유형을 가져야 하며 수정 가능한 l값이어야 한다.

그리고

사후 수정 ++ 연산자의 결과는 피연산자의 값이다.

C++고차스라는 책에는 이 사건도 수록되어 있다.Gotcha #17 Maximal Munch 문제 그것은 C++에서도 같은 문제이고 몇 가지 예를 들기도 한다.다음과 같은 문자 집합을 다룰 때는 다음과 같이 설명한다.

->*

어휘 분석기는 다음 세 가지 중 하나를 수행할 수 있다.

  • 다음 세 개의 토큰으로 처리하십시오.->그리고*
  • 두 개의 토큰으로 처리:->그리고*
  • 하나의 토큰으로 처리:->*

최대 우묵한 규칙으로 인해 이러한 애매한 점들을 피할 수 있다.저자는 (C++ 컨텍스트에서) 다음과 같이 지적한다.

그것이 야기하는 것보다 더 많은 문제를 해결하지만, 두 가지 일반적인 상황에서, 그것은 성가신 일이다.

첫 번째 예는 템플릿 인수가 템플릿(C++11에서 해결됨)인 템플릿이다. 예를 들어,

list<vector<string>> lovos; // error!
                  ^^

이는 닫히는 각 브래킷을 시프트 연산자로 해석하여 다음과 같이 모호하게 하기 위해 공간이 필요하다.

list< vector<string> > lovos;
                    ^

두 번째 경우는 다음과 같은 포인터의 기본 인수를 포함한다.

void process( const char *= 0 ); // error!
                         ^^

라고 해석될 것이다.*=할당 연산자, 이 경우 해결책은 선언문에 매개변수의 이름을 지정하는 것이다.

(a++)++ +b

a++는 이전 값인 r값을 반환한다.이건 증분할 수 없어.

렉서는 토큰을 만들기 위해 일반적으로 "maximum munch" 알고리즘을 사용한다.즉, 문자를 읽을 때 이미 가지고 있는 것과 같은 토큰의 일부가 될 수 없는 것을 만날 때까지(예를 들어 숫자를 읽고 있으면 숫자가 된다), 문자를 계속 읽게 된다는 뜻이다.A그게 숫자의 일부가 될 수 없다는 걸 알고 있어그래서 그것은 멈추고 그 곳을 떠난다.A다음 토큰의 시작 부분으로 사용할 입력 버퍼).그런 다음 그 토큰을 파서에게 돌려준다.

이 경우, 그것은 의미하는 것이다.+++++로 선택되다.a ++ ++ + b. 첫 번째 증가는 r값을 산출하기 때문에 두 번째 증가는 적용할 수 없고, 컴파일러는 오류를 준다.

단지 FWIW, C++에서는 과부하할 수 있다.operator++lvalue를 산출할 수 있도록 하는 겁니다.예를 들면 다음과 같다.

struct bad_code { 
    bad_code &operator++(int) { 
        return *this;
    }
    int operator+(bad_code const &other) { 
        return 1;
    }
};

int main() { 
    bad_code a, b;

    int c = a+++++b;
    return 0;
}

내가 가지고 있는 C++ 컴파일러(VC++, g+++, 코모)로 컴파일과 런(아무것도 하지 않지만)을 한다.

컴파일러는 이렇게 보는 것 같아.

c = ((a++)+++b

++수정될 수 있는 값을 피연산자로 가져야 한다.a는 수정할 수 있는 값이다. a++그러나 'rvalue'는 수정될 수 없다.

내가 GCC C에서 보는 오류는 같지만, 다른 말로 표현된다.lvalue required as increment operand.

컴파일러는 필사적으로 구문 분석하려고 한다.a+++++b, 그리고 그것을 로 해석하다.(a++)++ +b.자,후증가(후증가)의 결과.a++)은 l값(lvalue), 즉, 다시 후증가할 수 없다.

생산품질 프로그램에서는 절대로 그런 코드를 쓰지 마십시오.너의 코드를 해석해야 할 불쌍한 사람이 너를 쫓아오는 것을 생각해봐.

왜냐하면 그것은 정의되지 않은 행동을 일으키기 때문이다.

어느 쪽이야?

c = (a++)++ + b
c = (a) + ++(++b)
c = (a++) + (++b)

그래, 자네도 컴파일러도 그걸 몰라

편집:

진짜 이유는 다른 사람들이 말한 것이다.

된다.(a++)++ + b.

그러나 사후 증분에는 lvalue(이름이 있는 변수)가 필요하지만 (a++)는 증분할 수 없는 rvalue를 반환하여 오류 메시지를 받게 된다.

다른 사람들이 이것을 지적하도록 해라.

이 사전 결정 순서를 따르십시오.

1.++(사전 증가)

2.+ - (추출 또는 뺄셈)

3.x"+ "y" 순서 모두 추가

int a = 5,b = 2; printf("%d",a++ + ++b); //a is 5 since it is post increment b is 3 pre increment return 0; //it is 5+3=8

참조URL: https://stackoverflow.com/questions/5341202/why-doesnt-ab-work

반응형