2012-05-23 6 views
18

나는 원칙이 아마 정의되지 않은 동작 것을 알고 있지만, 대규모 프로젝트를 처리하는 이익, 여기에 GCC에 대한 내 질문 : 내가 사용 -std=c++11 하나의 transation의 gcc -std=c++98와 장치 및 다른 컴파일한다고 가정서로 다른 GCC 방언을 함께 연결할 수 있습니까?

똑같은 컴파일러 설치. 두 개의 오브젝트 파일을 연결하고 잘 정의 된 프로그램을 얻을 수 있다는 보장이 있습니까?

지금까지 내가, 잠재적 인 문제는 인해 다른 매크로에 대한 라이브러리 헤더의 다른 뷰에서 올 수 있고, 차례로 사람들은 기껏해야 받는 사람, 새 멤버 함수, 그러나 결코 구성원 개체를 추가 말할 수있는 표준 라이브러리 클래스.

다른 언어 언어 옵션으로 더 큰 프로젝트의 다른 부분을 컴파일하는 것이 허용됩니까?

업데이트 : 내가 직교 질문을 추가해야합니다 : 어떤 두 다른 GCC의 버전 (4.3 및 4.6를 말), 그러나 사용에 대한 WHT 같은 방언 옵션 (-std=c++98)? 목록 in this GCC documentation은 라이브러리가 4.2.2와 4.6 사이의 양방향으로 호환 가능하다고 제안하는 것으로 보입니다.

답변

10

선험, 아니오. 가장 안전한 해결책은 컴파일러 옵션의 모든이 동일하다고 가정하는 것입니다. 단, 컴파일러에서이 옵션이 바이너리 호환성에 영향을 미치지 않는다고 특별히 명시한 경우는 예외입니다. (실제로는 대부분의 컴파일러에서 부족한 문서입니다.) 실제로 설명서가 부족하기 때문에 경고를 제어하는 ​​옵션 (g ++에서 -W...)은 바이너리 호환성에 영향을 미치지 않으며 코드 생성에 영향을주는 옵션 언어 수준 등) : g ++은 일반적으로 서로 다른 수준의 최적화, 즉 VC++에서 호환성을 유지합니다.

또 다른 실제 문제는 명령 줄에서 선처리 기호를 정의하는 것입니다. 다시 말하지만 가장 안전한 방법은 모든 정의가 동일해야한다는 것입니다. 다시 한번, 몇 가지 상식이 있습니다 : 표준 라이브러리가 프로젝트에서 사용되는 전처리 기 기호 (예 : MYPROG_CONFIG_FILE_LOCATION, 말하다). 한편, 사전 처리기 정의가 _GLIBCXX_DEBUG_GLIBCXX_DEBUG_PEDANTIC 일 경우 이진 호환성에 영향을 미칩니다 (g ++에서는 일관성있게 사용하는 경우 g ++에서 해당 라이브러리 버전을 사용할 수 있습니다). 귀하의 질문에 관해서

: 선택은 끊을 방법으로, 몇 가지 미리 정의 된 처리기 기호에 영향을 미치는 경우, 나는 그것으로 인해 거의 나를 놀라게하지 않을 것이다 표준 버전, 하지만에 바이너리 호환성에 큰 영향을 기대하지 않을 것이다 라이브러리의 바이너리 호환성. 마치 모듈 중 일부를 _GLIBCXX_DEBUG으로 컴파일 한 것처럼 보이지만 일부는 컴파일하지 않은 것입니다. 그것은 효과가 있을지 모르지만 나는 그것에 의지하지 않을 것이다.

+1

"사람이 거의 표준 라이브러리 프로젝트에서 사용되는 전 처리기 기호로 컴파일 된 것으로 기대할 수 없다"- 그것은 경우에도, 그리고 순간 매크로 가정 :

은 또한 관련 참조 'MYPROG_CONFIG_FILE_LOCATION'이'memset.c'에서 사용되면,'memset.c'에 정의 된 의미는 프로그램에서의 의미와 완전히 관련이 없습니다. 그러므로'MYPROG_CONFIG_FILE_LOCATION'과 함께 /하지 않고'memset.c'를 컴파일하면 바이너리 호환성에 차이가 생깁니다. 그렇다면 프로그램이 MYPROG_CONFIG_FILE_LOCATION을 사용하는지 여부와 관계없이 독립적으로 수행 할 것입니다. –

+0

@SteveJessop 예. 그것이 있었다고하더라도, 그것은 당신에게 투명해야합니다. 실제로 네임 스페이스의 모든 전처리 기 기호 (즉, 밑줄로 시작하지 않고 두 개의 밑줄을 포함하지 않음)은 안전해야합니다. 구현 네임 스페이스의 '_GLIBCXX_DEBUG'와 같은 전 처리기 심볼은 그렇지 않습니다. –

3

나는 원칙적으로이 아마 정의되지 않은 동작 것을 알고,

이 아니다. 가정하자

나는 똑같은 컴파일러 설치를 사용하여, -std=c++11 하나의 transation의 gcc -std=c++98와 장치 및 다른 컴파일. 두 개의 오브젝트 파일을 연결하고 잘 정의 된 프로그램을 얻을 수 있다는 보장이 있습니까?

네,이 지원되고 작업 (이 예외가 하나 -fshort-enums가 아닌 다른과 같은 명시 적으로-ABI가 변화하는 옵션을 하나의 객체에서 디버그 모드를 활성화하지 다른, 또는 사용처럼,하지만 그해야 두 개체 모두에 동일한 -std 옵션을 사용하더라도 작동하지 않으므로 분명해야합니다.

지금까지 내가 말할 수있는, 잠재적 인 문제는 인해 다른 매크로에 대한 라이브러리 헤더의 다른 뷰에서 올 수 있고, 차례로 사람들은 기껏에, 새 멤버 함수, 그러나 결코 구성원 개체를 추가 표준 라이브러리 클래스.

오른쪽.

다른 언어 언어 옵션으로 더 큰 프로젝트의 다른 부분을 컴파일하는 것이 허용됩니까?

그래, 절대적으로. 증명을 위해, libstdc++.so 자체에는 -std=c++98으로 빌드 된 오브젝트와 -std=c++14으로 빌드 된 오브젝트가 포함되어 있다고 생각하십시오.

업데이트 : 직교 질문을 추가해야합니다 : 어떤 GCC의 두 가지 버전 (4.3 및 4.6 말) 사용에 대한,하지만 WHT 같은 방언 옵션 (-std는 = C++ 98)? 이 GCC 문서의 목록은 라이브러리가 4.2.2와 4.6 사이의 양방향으로 호환 가능하다고 제안하는 것으로 보인다. 해당 버전으로 컴파일 된 객체가 새로운 버전에 도입과에 존재하지 않는 한 문자에 의존 수 있기 때문에

는 양 방향으로, 당신은 GCC 4.6 (이상)에서 libstdc++.so를 사용할 필요가 없음 이전 libstdc++.so 라이브러리

https://stackoverflow.com/a/49119902/981959

0

언어 ABI에서 일부 관련 정보는 동일하지만, STL ABI는 다르다. https://gcc.gnu.org/wiki/Cxx11AbiCompatibility

-std = C++ 98 -std = C++ 11로 컴파일 된 라이브러리를 혼합하지 않는 것이 좋습니다. 이미지 경계를 넘어 데이터를 전달할 때 충돌이 발생할 수 있습니다.

(extern "C"함수 만 호출하고 POD 만 전달하면 작동 할 수 있습니다). Mixing different C++ standards with GCC

+0

그 wiki 페이지가 최신 것처럼 보이지 않습니다 :-( –