Programming

컴파일러가 누락 된 세미콜론을보고하지 않는 이유는 무엇입니까?

procodes 2020. 7. 28. 22:05
반응형

컴파일러가 누락 된 세미콜론을보고하지 않는 이유는 무엇입니까?


이 간단한 프로그램이 있습니다.

#include <stdio.h>

struct S
{
    int i;
};

void swap(struct S *a, struct S *b)
{
    struct S temp;
    temp = *a    /* Oops, missing a semicolon here... */
    *a = *b;
    *b = temp;
}

int main(void)
{
    struct S a = { 1 };
    struct S b = { 2 };

    swap(&a, &b);
}

예를 들어 ideone.com에서 볼 수 있듯이 오류가 발생합니다.

prog.c: In function 'swap':
prog.c:12:5: error: invalid operands to binary * (have 'struct S' and 'struct S *')
     *a = *b;
     ^

컴파일러가 누락 된 세미콜론을 감지하지 못하는 이유는 무엇입니까?


참고 :이 질문과 답변은 이 질문에 의해 동기가 부여됩니다 . 이와 비슷한 다른 질문 이 있지만이 언어 및 관련 오류의 원인이되는 C 언어의 자유 형식을 언급하는 것을 찾지 못했습니다.


C는 자유 형식 언어입니다. 즉, 여러 가지 방법으로 형식을 지정할 수 있으며 여전히 법적 프로그램입니다.

예를 들어

a = b * c;

다음과 같이 쓸 수 있습니다

a=b*c;

또는 좋아

a
=
b
*
c
;

컴파일러가 라인을 볼 때

temp = *a
*a = *b;

그것은 그것이 의미하는 것으로 생각

temp = *a * a = *b;

그것은 물론 유효한 표현이 아니며 컴파일러는 누락 된 세미콜론 대신 그것에 대해 불평합니다. 유효하지 않은 이유 a는 구조에 대한 포인터 이기 때문에 *a * a구조 인스턴스 ( *a)에 구조 에 대한 포인터 ( ) 를 곱하려고하기 때문 입니다 a.

컴파일러는 누락 된 세미콜론을 감지 할 수 없지만 잘못된 행에 완전히 관련되지 않은 오류도보고합니다. 오류가보고 된 행을 얼마나 많이 보더라도 오류가 없으므로주의해야합니다. 때때로 이와 같은 문제는 이전 줄을보고 문제가 없는지 확인해야합니다.

Sometimes you even have to look in another file to find the error. For example if a header file is defining a structure the last it does in the header file, and the semicolon terminating the structure is missing, then the error will not be in the header file but in the file that includes the header file.

And sometimes it gets even worse: if you include two (or more) header files, and the first one contains an incomplete declaration, most probably the syntax error will be indicated in the second header file.


Related to this is the concept of follow-up errors. Some errors, typically due to missing semicolons actually, are reported as multiple errors. This is why it's important to start from the top when fixing errors, as fixing the first error might make multiple errors disappear.

This of course can lead to fixing one error at a time and frequent recompiles which can be cumbersome with large projects. Recognizing such follow-up errors is something that comes with experience though, and after seeing them a few times it's easier to dig out the real errors and fix more than one error per recompile.


Why doesn't the compiler detect the missing semicolon?

There are three things to remember.

  1. Line endings in C are just ordinary whitespace.
  2. * in C can be both a unary and a binary operator. As a unary operator it means "dereference", as a binary operator it means "multiply".
  3. The difference between unary and binary operators is determined from the context in which they are seen.

The result of these two facts is when we parse.

 temp = *a    /* Oops, missing a semicolon here... */
 *a = *b;

The first and last * are interpreted as unary but the second * is interpreted as binary. From a syntax perspective, this looks OK.

It is only after parsing when the compiler tries to interpret the operators in the context of their operand types that an error is seen.


Some good answers above, but I will elaborate.

temp = *a *a = *b;

This is actually a case of x = y = z; where both x and y are assigned the value of z.

What you are saying is the contents of address (a times a) become equal to the contents of b, as does temp.

In short, *a *a = <any integer value> is a valid statement. As previously pointed out, the first * dereferences a pointer, while the second multiplies two values.


Most compilers parse source files in order, and report the line where they discover that something was wrong. The first 12 lines of your C program could be the start of a valid (error-free) C program. The first 13 lines of your program cannot. Some compilers will note the location of things they encounter which are not errors in and of themselves, and in most cases won't trigger errors later in the code, but might not be valid in combination with something else. For example:

int foo;
...
float foo;

The declaration int foo; by itself would be perfectly fine. Likewise the declaration float foo;. Some compilers may record the line number where the first declaration appeared, and associate an informational message with that line, to help the programmer identify cases where the earlier definition is actually the erroneous one. Compilers may also keep the line numbers associated with something like a do, which can be reported if the associated while does not appear in the right place. For cases where the likely location of the problem would be immediately preceding the line where the error is discovered, however, compilers generally don't bother adding an extra report for the position.

참고URL : https://stackoverflow.com/questions/40135392/why-doesnt-the-compiler-report-a-missing-semicolon

반응형