“파일 끝에 줄 바꿈 없음”컴파일러 경고


187

일부 C ++ 컴파일러에서 다음 경고가 발생하는 이유는 무엇입니까?

파일 끝에 줄 바꿈이 없습니다.

소스 / 헤더 파일 끝에 빈 줄이 있어야하는 이유는 무엇입니까?


17
아니 진짜 이유는,하지만 당신의 경우 매우 짜증나 cat파일 및 프롬프트 새로운 쉘이 파일의 마지막 행 다음에 나타납니다으로는 (열이 아닌 0에서 예) 뒤에 줄 바꿈이 없습니다
ThiefMaster

@ThiefMaster My $ PS1은 바로 이런 이유로 개행으로 시작합니다. (어쨌든 그것은 한 줄에 유용한 정보를 많이 포함하고 다음 줄에 프롬프트 문자 만 포함하여 여러 줄 프롬프트이므로 상당히 긴 명령이 래핑되지 않습니다)
bames53

7
Why should I have an empty line at the end of a source/header file-텍스트 파일에 one\ntwo\nthree\n세 개의 줄이 포함 되어 있으며 그 중 하나는 비어 있지 않습니다. 텍스트 파일에 텍스트 파일이 포함되어 있으면 텍스트 파일 one\ntwo\nthree이 아니며 끝에서 완전히 멈추지 않은 문장은 문장이 아닙니다.
Brandin

답변:


217

줄 바꿈이 없을 때 발생할 수있는 문제 중 일부를 생각해보십시오. ANSI 표준에 따르면 #include처음에 파일의 파일은 파일의 앞쪽에있는 그대로 파일을 삽입 #include <foo.h>하고 파일의 내용 뒤에 새 줄을 삽입하지 않습니다 . 따라서 파서 끝에 줄 바꿈이없는 파일을 포함하면 파일의 마지막 줄이 foo.h의 첫 번째 줄과 같은 줄에있는 것처럼 보입니다 foo.cpp. foo.h의 마지막 줄이 새로운 줄이없는 주석이라면? 이제 첫 줄 foo.cpp이 주석 처리됩니다. 이들은 발생할 수있는 문제 유형의 몇 가지 예일뿐입니다.


아래의 제임스의 답변에 관심있는 당사자를 지적하고 싶었습니다. 위의 대답은 여전히 ​​C에 맞지만 새로운 C ++ 표준 (C ++ 11)이 변경되어 C ++ 및 C ++ 11을 준수하는 컴파일러를 사용할 경우이 경고가 더 이상 발행되지 않도록합니다.

James의 게시물을 통해 C ++ 11 표준에서 :

비어 있지 않고 개행 문자로 끝나지 않거나 그와 같은 스 플라이 싱이 발생하기 직전에 백 슬래시 문자 바로 앞에있는 개행 문자로 끝나는 소스 파일은 추가의 새로운 것처럼 처리해야합니다. 줄 문자가 파일에 추가되었습니다 (C ++ 11 §2.2 / 1).


28
실제로 모든 컴파일러는 #include 뒤에 새 줄을 추가합니다. 고맙게도
mxcl

3
나는 이전 버전의 Microsoft Visual C ++ (2.x 등)가 정확히이 문제를 가지고 있다고 생각합니다. IDE 편집기가 이런 종류의 누락 된 줄 바꿈 동작을 권장했기 때문에 악화되었습니다.
Greg Hewgill

2
컴파일러는 현재 불평하지 않을 수 있지만 실제로 GitHub는 그렇게합니다.
Puyover

1
James"아래"답변을 볼 수 있지만 OrderBy의 "위 답변"은 무엇입니까?! 위의 질문은 보통 투표로 주문하는 것입니다. 아니면 자신의 대답을 의미합니까?
mbx

@Thomas :이 프로그램은 줄 바꾸기로 끝나지 않기 때문에 정의되지 않은 동작을 호출합니까? 여기에서 프로그램을보십시오 : ideone.com/jswwf9
소멸자

44

모든 소스 파일이 이스케이프되지 않은 줄 바꿈으로 끝나야한다는 요구 사항이 C ++ 11에서 제거되었습니다. 이제 스펙은 다음과 같습니다.

비어 있지 않고 개행 문자로 끝나지 않거나 그와 같은 스 플라이 싱이 발생하기 직전에 백 슬래시 문자 바로 앞에있는 개행 문자로 끝나는 소스 파일은 추가의 새로운 것처럼 처리해야합니다. 줄 문자가 파일에 추가되었습니다 (C ++ 11 §2.2 / 1).

적합한 컴파일러는 더 이상이 경고를 발행하지 않아야합니다 (컴파일러에 언어 사양이 다른 개정 모드가있는 경우 C ++ 11 모드에서 컴파일 할 때).


4
그것은 모두 C ++에 좋고 훌륭합니다. 불행히도 C는 앞으로 나올 C1X 표준 초안에서도 여전히 UB라고 말합니다.
Adam Rosenfield

11
이 질문은 [c]가 아닌 [c ++]로 태그되어 있습니다.
James McNellis

3
그럼에도 불구 하고 C에서이 경고를 검색하는 많은 사람들이 여기에서 자신의 길을 찾을 수 있기 때문에 아마도 [c]로 표시 되어야 합니다.
Adam Rosenfield

1
이것은 여전히 ​​좋은 지적입니다. 이것을 위에 추가하십시오. 당신이 상관하지 않기를 바랍니다.
TJ Seabrooks

25

C ++ 03 표준 [2.1.1.2]는 다음을 선언합니다.

... 비어 있지 않은 소스 파일이 개행 문자로 끝나지 않거나 그러한 스 플라이 싱이 발생하기 전에 백 슬래시 문자 바로 앞에있는 개행 문자로 끝나는 경우 동작이 정의되지 않습니다.



6

빈 줄을 나타내는 것이 아니라 마지막 줄 (내용을 포함 할 수있는)이 줄 바꿈으로 끝나는 지 여부입니다.

대부분의 텍스트 편집기는 파일의 마지막 줄 끝에 줄 바꿈을 추가하므로 마지막 줄에 줄이 없으면 파일이 잘릴 위험이 있습니다. 그러나 줄 바꿈을 원하지 않는 올바른 이유가 있으므로 오류가 아니라 경고 일뿐입니다.


5

#include줄을 파일의 리터럴 내용으로 바꿉니다. 파일이 줄 바꿈으로 끝나지 않으면 파일 #include을 가져온 줄이 포함 된 줄이 다음 줄과 병합됩니다.


2

나는 c-free IDE 버전 5.0을 사용하고 있는데 'c ++'또는 'c'언어 중 하나의 프로그램에서 동일한 문제가 발생했습니다. 프로그램의 끝프로그램의 마지막 줄에 main 또는 any function)에서 enter -line no를 누르십시오 . 1. 같은 프로그램을 실행하면 오류없이 실행됩니다.


2

실제로 모든 컴파일러는 #include 뒤에 새로운 줄을 추가합니다. 고맙게도 – @mxcl

특정 C / C ++이 아니라 C 방언 : GL_ARB_shading_language_include확장을 사용하면 OS X의 glsl 컴파일러는 줄 바꿈에 대해 경고 하지 않습니다 . 당신은 쓸 수 있도록 MyHeader.h로 끝나는 헤더 가드 파일을 #endif // __MY_HEADER_H__당신은 것입니다 애프터 선을 잃을 #include "MyHeader.h"확실히.


2

파일이 개행으로 끝나지 않으면 C / C ++ 버전마다 동작이 다르기 때문입니다. 특히 불쾌한 것은 오래된 C ++ 버전이며 C ++ 03의 fx는 표준에 따르면 (번역 단계)는 다음과 같습니다.

비어 있지 않은 소스 파일이 개행 문자로 끝나지 않거나 바로 앞에 백 슬래시 문자가있는 개행 문자로 끝나는 경우 동작이 정의되지 않습니다.

정의되지 않은 동작은 좋지 않습니다. 표준 준수 컴파일러는 여기에서 원하는 것을 수행 할 수 있습니다 (악성적인 코드 삽입 등) – 분명 경고 이유.

C ++ 11에서는 상황이 더 좋지만 이전 버전에서는 동작이 정의되지 않은 상황을 피하는 것이 좋습니다. C ++ 03 스펙은 C99보다 나빠서 이러한 파일을 완전히 금지합니다 (동작이 정의 됨).


나는 표준에 따르면 줄 바꿈이없는 프로그램은 형식이 잘못되었다고 말하는 대신 정의되지 않은 동작을 가지고 있다고 생각합니다. 일부 컴파일러는 포함 된 파일의 종료되지 않은 최종 행을 #include지시문 뒤에 소스 코드 텍스트와 연결하기 때문입니다. 이러한 컴파일러를 대상으로하는 일부 프로그래머는 이러한 동작을 악용했을 수 있습니다. 표준이 그러한 것들을 정의하지 않은 상태로두면 그러한 특징을 이용하는 프로그램은 그러한 행동을 명시하는 플랫폼에서 잘 정의 될 수 있습니다. 표준에 따라 행동을 취하면 그러한 프로그램이 중단 될 수 있습니다.
supercat

0

이 경고는 파일이 어떻게 든 잘릴 수 있음을 나타내는 데 도움이 될 수 있습니다. 컴파일러가 어쨌든 컴파일러 오류를 던질 것입니다. 특히 함수 중간에 있거나 링커 오류 일 가능성이 높지만 더 암호가 많을 수 있으며 보장되지는 않습니다.

물론 개행 직후 파일이 잘 리면이 경고가 보장되지 않지만 다른 오류가 누락되어 문제에 대한 더 강력한 힌트를 줄 수있는 경우가있을 수 있습니다.


-2

그것은 오류가 아닙니다. 경고 일뿐입니다.

편집기에서 파일을 열고 파일의 마지막 줄로 이동 한 후 Enter 키를 눌러 파일 끝에 빈 줄을 추가하십시오.

그러나 그 외에도을 #include <iostream>대신 사용해야합니다 <iostream.h>. 그런 다음 using std::cout;그것을 넣 습니다.

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