programing

"../include/header"와 같은 상대 경로의 이점은 무엇입니까?h"는 헤더에 사용할 수 있습니까?

copysource 2022. 8. 28. 19:03
반응형

"../include/header"와 같은 상대 경로의 이점은 무엇입니까?h"는 헤더에 사용할 수 있습니까?

올바른 사용 방법 include direction과 C++ #include semantics를 포함질문을 검토했습니다.또한 제목을 입력할 때 SO가 제안한 다른 질문도 검토하지 않았습니다.

글쓰기의 장점은 무엇입니까?

#include "../include/someheader.h"
#include "../otherdir/another.h"

일반 파일 이름만 사용하는 경우:

#include "someheader.h"
#include "another.h"

또는 ''가 없는 상대적인 이름일 수도 있습니다...':

#include "include/someheader.h"
#include "otherdir/another.h"

표시되는 문제는 다음과 같습니다.

  • 헤더를 이동하려면 헤더를 포함하는 소스 파일을 고려해야 합니다.
  • 의존관계 및 오류 보고서의 헤더에 대해 매우 긴 경로를 사용할 수 있습니다.난 오늘 "와 한 잔 했다"../dir1/include/../../include/../dir2/../include/header.h".

제가 볼 수 있는 유일한 장점은 파일을 이동할 필요가 없지만 항상 사용하지 않고도 빠져나갈 수 있다는 것입니다.-I헤더를 찾는 지시는 있습니다만, 유연성의 상실, 서브 서브 서브 디렉토리의 컴파일의 복잡성 등, 메리트가 큰 것 같습니다.

제가 혜택을 간과하고 있는 건가요?


조언해 주셔서 감사합니다.저는 ".."를 사용하는 표기법에는 큰 이점이 없다는 데 공감대가 있다고 생각합니다.내가 간과하고 있다는 걸.일반적으로, 저는 "어디선가/헤더"를 좋아합니다.h" 표기법입니다.새로운 프로젝트에서 사용합니다.지금 작업 중인 건 전혀 새롭지 않아요.

문제의 1개는 다음과 같은 프레픽스를 가진 다양한 헤더 세트가 있다는 것입니다.rspqr.h,rsabc.h,rsdef.h,rsxyz.h이것들은 모두 의 코드와 관련되어 있습니다.rsmp디렉토리입니다만, 일부의 헤더는rsmp그 외의 디렉토리는 중앙의 include 디렉토리에 있습니다.이 디렉토리에는, 다음과 같은 서브 디렉토리가 없습니다.rsmp(그리고 코드의 다른 다양한 영역에 대해서도 반복합니다.여러 위치에 헤더가 있어 다른 코드 비트에 의해 랜덤하게 요구됩니다.)몇 년 동안 코드가 너무 복잡해졌기 때문에 물건을 옮기는 것은 큰 문제입니다.그리고 메이크파일이 일치하지 않아-I옵션이 준비되어 있습니다.대체로, 그것은 수십 년 동안 그다지 공평하지 않은 태만의 슬픈 이야기다.아무것도 망가뜨리지 않고 모든 것을 고치는 것은 길고 지루한 일이 될 것이다.

경로 구문은 헤더 파일이 어떤 네임스페이스 또는 모듈에 속하는지 명확하게 하기 때문에 선호합니다.

#include "Physics/Solver.h"

모든 모듈이 헤더 파일에 이름을 붙일 필요 없이 매우 자기 설명이 가능합니다.

저는 ".." 구문을 거의 사용하지 않지만, 대신 올바른 베이스 위치를 지정하는 프로젝트를 수행하게 됩니다.

에 관한 문제#include "../include/header.h"그것은 종종 우연히 작동하게 되고, 겉보기에는 관련이 없어 보이는 변화가 나중에 작동을 멈추게 된다는 것이다.

예를 들어 다음과 같은 소스 레이아웃을 고려합니다.

./include/header.h
./lib/library.c
./lib/feature/feature.c

컴파일러를 include 경로로 실행하고 있다고 칩시다.-I. -I./lib어떻게 되는 거죠?

  • ./lib/library.c할 수 있다#include "../include/header.h"말이 되네.
  • ./lib/feature/feature.c할 수도 있다#include "../include/header.h"말도 안 되는 일이지만요이는 컴파일러가 다음 명령을 시도하기 때문입니다.#include현재 파일의 위치에 대한 지시문입니다.이것이 실패했을 경우, 이 지시문은#include각각에 대한 지시-I에의 엔트리#include경로.

게다가 나중에 삭제하면-I./lib에서#include패스, 그러면 브레이크가./lib/feature/feature.c.

다음과 같은 것이 바람직하다고 생각합니다.

./projectname/include/header.h
./projectname/lib/library.c
./projectname/lib/feature/feature.c

다음 이외의 include path 엔트리는 추가하지 않습니다.-I., 그리고 둘 다library.c그리고.feature.c사용하다#include "projectname/include/header.h". "projectname"이 고유할 가능성이 높다고 가정하면 대부분의 경우 이름 충돌이나 모호성이 발생하지 않습니다.또한 포함 경로 및/또는 제조 방법을 사용할 수 있습니다.VPATH꼭 필요한 경우 프로젝트의 물리적 레이아웃을 여러 디렉터리로 분할하는 기능(플랫폼 고유의 자동 생성 코드를 수용하기 위해 등)을 제공합니다.이 기능은 사용 시 실제로 중단됩니다.#include "../../somefile.h").

IANALL, 하지만 난 네가 이 모든 걸 포기하면 안 된다고 생각해...는 실제 C 또는 C++ 소스 파일에 포함되어 있습니다.이는 포터블이 아니기 때문에 표준에서는 지원되지 않기 때문입니다.이것은 사용법과 유사합니다.\는 Windows 상에 있습니다.컴파일러가 다른 방법으로 동작할 수 없는 경우에만 실행해 주세요.

의 경로를 시작합니다.#include ""1개 이상의 연속된 명령어../"의 경우:

  • 인크루드 파일과의 연관성이 고정된 파일을 포함시키고 싶다.
  • POSIX 시스템 또는 VC++를 사용하여 빌드하고 있는 경우
  • 어떤 파일이 포함될지 애매한 상황을 피하고 싶다.

코드 베이스에 에러가 포함되어 있는 장소와 그 후에 진단하기 어려운 에러가 발생하는 장소의 예를 항상 간단하게 제시할 수 있습니다.그러나 프로젝트에 장애가 없는 경우에도 절대 경로를 사용하여 서로 상대적인 파일을 지정할 경우 타사로부터 악용될 수 있습니다.

예를 들어 다음과 같은 프로젝트 레이아웃을 고려하십시오.

./your_lib/include/foo/header1.h
./your_lib/include/bar/header2.h
./their_lib/include/bar/header2.h

your_lib/include/foo/header1.h는 어떻게 your_lib/include/bar/header2.h를 포함합니까?다음 두 가지 옵션을 생각해 보겠습니다.

  1. #include <bar/header2.h>

    헤더 검색 경로로 your_lib/include그들의_lib/include가 모두 인용되어 있다고 가정합니다(예를 들어 GCC 사용).-I또는-isystemoptions)에서는 헤더 2.h를 선택하는 방법은 이들 2개의 경로가 검색되는 순서에 따라 달라집니다.

  2. #include "../bar/header2.h"

    컴파일러가 검색되는 첫 번째 장소는 your_lib/include/foo/header1.h 로, your_lib/include/foo/ 입니다.먼저 your_lib/include/foo/../bar/header2.h를 시도합니다.이 값은 your_lib/include/bar/header2.h로 감소하며 올바른 파일을 찾을 수 있습니다.헤더 검색 경로는 전혀 사용되지 않으며 애매모호할 여지가 거의 없습니다.

이 경우 주어진 이유로 옵션 2)를 적극 추천합니다.

다른 답변의 일부 인수에 대한 응답:

  • @syslog-syslog는 다음과 같이 말합니다.

    ... 헤더 파일이 속한 네임스페이스 또는 모듈이 매우 명확해집니다.

    그럴지도 모르지만 상대 경로는 "이러한 모듈에서"로 해석될 수 있습니다.다른 모듈에 같은 이름의 디렉토리가 여러 개 있는 경우, 이러한 디렉토리는 명확성을 제공합니다.

  • @bk1e:

    ...그것은 종종 우연히 작동한다...

    상대 경로가 우연히 작동하게 되는 경우는 매우 드물지만 프로젝트가 처음부터 고장나 쉽게 수리될 수 있습니다.컴파일러 에러를 일으키지 않고, 이러한 이름의 충돌이 발생하는 것은 거의 없는 것 같습니다.일반적인 시나리오는 종속 프로젝트의 파일에 다른 헤더가 포함된 헤더 중 하나가 포함된 경우입니다.테스트 스위트를 컴파일하면 종속 프로젝트와 분리하여 컴파일할 때 "No scho file or directory" 오류가 발생합니다.

  • @singlengulation elimination은 말한다.

    ...휴대용도 아니고 표준 규격에서도 지원되지 않습니다.

    ISO C 표준은 프로그램이 컴파일 또는 실행되는 시스템의 모든 세부사항을 규정하지 않을 수 있습니다.즉, C가 동작하는 플랫폼을 표준이 과도하게 특정하지 않는 것을 의미합니다.(그 방법과의 차이)""그리고.<>는 POSIX 표준에서 유래한 일반적인 현대 시스템에서 해석됩니다.)

  • @syslog-syslogll이 말한다.

    ".."는 상대적인 위치를 가정하고 취약하다.

    어떻게 연약해?아마도 두 파일의 조합에 민감할 것입니다.그 때문에,..「」는, 인크루드 파일의 작성자가 그 위치를 제어할 때만(그리고 항상) 사용합니다.

소스 트리를 네스트된 네임스페이스로 생각하면 포함 경로를 통해 디렉토리를 이 네임스페이스의 루트로 가져올 수 있습니다.이 질문은 코드가 디스크에서 어떻게 구성되어 있는지에 관계없이 코드 베이스의 논리 네임스페이스를 형성하는 것입니다.

나는 다음과 같은 경로를 피하고 싶다.

  • "include/foo/bar.h"- "비논리적이고 중복된" 것 같다.
  • "../foo/bar.h"- ".."는 상대적인 위치를 가정하여 취약합니다.
  • "bar.h"bar.h가 현재 디렉토리에 없는 한 글로벌네임스페이스를 오염시켜 애매성을 요구합니다.

개인적으로는 다음과 같은 경로를 프로젝트에 추가하는 경향이 있습니다."..;../..;../../..;../../../..".

이것에 의해, 데이터 베이스에 숨김의 룰을 적용할 수 있습니다.#include를 사용하면 다른 코드를 끊지 않고 헤더를 자유롭게 이동할 수 있습니다.물론 이는 정규화되지 않은 이름이 모호할 수 있으므로 주의하지 않으면 잘못된 헤더 파일에 바인딩될 위험이 있습니다.

나는 완전히 자격증을 따는 경향이 있다.#include퍼블릭 헤더에 저장되므로 내 코드를 사용하는 서드파티에서는"..;../..;../../..;../../../.."개인 코드와 빌드 시스템의 편리함일 뿐입니다.

상대 경로가 있는 윈도의 또 다른 문제는 MAX_PATH입니다.이것은 예를 들어 안드로이드용 크로스 컴파일과 패스 길이가 260을 초과할 때 컴파일 문제를 일으킵니다.

프로젝트 루트에 상대적인 파일을 배치하고 소스 제어에 체크 아웃하면 다른 개발자가 로컬 시스템 상의 다른 위치로 체크 아웃하면 계속 작동합니다.

절대(또는 "확장된 친척")에 대한 또 다른 인수는 다음과 같은 경로를 포함합니다.#include "./lib/subdir/~/subsubsubsubdir/header.h"...대규모 프로젝트에서는 많은 작업이 필요할 수 있습니다."-I./~"옵션을 선택합니다.현재 프로젝트에서는 이러한 옵션이 차지하는 문자 수가 거의 40k로 명령줄 제한으로 인해 오류가 발생합니다.

나는 보통 그러한 스타일의 포함 경로가 명백하게 융통성 없는 것을 싫어하지만, 그것은 이런 종류의 문제를 피하는 데 도움이 될 수 있다.예를 들어 정적 라이브러리는 다음 API를 통해 제공할 수 있습니다."#include "lib_api.h"그 외의 모든 조직은 그 장소에 대해 상대적이며 사용자에게 보이지 않을 수 있습니다.

언급URL : https://stackoverflow.com/questions/597318/what-are-the-benefits-of-a-relative-path-such-as-include-header-h-for-a-hea

반응형