2010-07-21 2 views
7

표준 준수 C++ 구현은 동일한 입력 데이터를 사용하여 같은 컴파일 된 한 번 프로그램의 실행이 서로 다른 방식으로 표준에서 구현 정의 된 동작을 구현할 수 있습니까?구현 정의 동작은 C++에서의 실행간에 일관성이 있어야합니까?

예를 들어 "주말에는 행동이며 그렇지 않은 경우"라고 말할 수있는 구현이 있으며 그러한 진술에 따라 동작을 구현합니까?

+2

마음에 구체적인 예가 있습니까? 번갈아서 "구현 정의"를 정확히 의미하고 구현자가 일관성을 보장한다면 일관성을 기대하십시오. 그렇지 않으면 모든 베팅이 해제됩니다 – msw

+3

GCC는 정의되지 않은 동작으로 훨씬 더 멋있었습니다 : http : //en.wikipedia .org/wiki/Undefined_behavior # Compiler_easter_eggs – sarnold

답변

1

구현 정의 된 동작은 의미

각 구현 문서은 선택이 어떻게 만들어 지는지

Unspeci Fi를 에드 행동

그것은 특정 프로그램의 동작을 문서화하는 컴파일러 작가 필수입니다 특정 구현을위한 구성.

..... 동일한 입력 데이터를 사용하여 같은 컴파일 된 프로그램을 여러 번 실행하는 것과 다른 방식으로?

Nopes!

예를 들어 "주말에는 행동이며 그렇지 않은 경우"라고 말하면서 그런 진술에 따라 행동을 구현할 수 있습니까?

확실하지 않지만 대답은 아니요,입니다.

+4

이것이 허용되지 않는 이유는 알 수 없습니다. 표준은 "어느 선택이 이루어지는가"가 아니라 "선택이 이루어지는 방법"이라고 말합니다. – sharptooth

+3

필자가 보았 듯이, 구현 정의 된 동작의 정의는 각 사례가 발생할 때 정확하게 그리고 각 상황에 대해 정확히 발생하는 경우 실행 간 차이의 가능성을 배제하지 않습니다. –

+1

@sharptooth : 내 대답을 편집했지만, 첫 번째 질문에 대한 대답이 '아니오'라는 확신이 거의 확실합니다. 예를 들어,'sizeof (int)'를 고려하면 (구현체가 동작을 문서화 한대로) 특정 구현에 대해 수정 된 상태로 유지된다는 것이 보장됩니다. .... 나는 약간 혼란스럽고'이런 문에 따라 행동을 구현 하는가? ' –

0

rand(3)<stdlib.h>은 C++에서 호출 할 수 있지만 "표준 C++"에 C 라이브러리가 얼마나 많이 포함되어 있는지는 모르지만 난수 생성에 대한 표준 준수 메커니즘이 있습니다.

time(3)<time.h>은 현재 시간을 반환합니다. C++과 동일한 이야기와 C 라이브러리 호출.

+1

이것은 질문과 어떻게 관련이 있습니까? – Naveen

+0

'rand()'또는'time()'은 구현 정의로 라벨이 붙어 있습니까? 나는 그들이 존재한다고 추정 할 수 있으며, 그렇다면 실제로 반례가 될 것입니다. 글쎄, 현재 시간 및/또는 시스템 RNG 상태가 입력의 일부라고 생각하지 않는 한. –

+0

@naveen, 나는 표준에서'rand()'가 지정되었다고 가정했지만 세부 사항은 구현에 따라 정의되었다. 이 가정을 확인하는 데 문제가 있습니다. – sarnold

6

물론 실행이 다른 실행과 정확히 바뀌면 구현 문서에서 설명하는 것이 좋습니다. 이 규격에서

의미 론적 설명은 매개 변수가 결정적 추상적 기계를 정의 구현 정의 동작은 추상 기계의 매개 변수의 일부임을 알 수 있습니다.

추상 기계의 특정 측면 및 연산은이 표준에서 구현 정의 (예 : sizeof (int))로 설명됩니다. 이것들은 추상 기계의 매개 변수를 구성합니다. 각 구현에는 이러한 측면에서 특성과 동작을 설명하는 문서가 포함되어야합니다. 그러한 문서는 해당 구현에 해당하는 추상 기계의 인스턴스를 정의해야한다 (아래의 "해당 인스턴스"라고 함).

이렇게하면 컴파일러를 한 번 실행해도 동작이 변경되지 않습니다.그러나 컴파일러가 서로 다른 경우 컴파일러는 구현 정의에 따라 서로 다른 구현 정의 값에 따라 다른 서로 다른 추상 기계를 사용할 수 있습니다. -Wall과 같은 명령 줄 매개 변수 (구현 정의 진단 메시지 집합을 변경 함)가 가장 일반적인 예입니다. 이는 문서화 요구 사항 외에도 불특정 행동에 대한 차이입니다. 지정되지 않은 행동은 훨씬 덜 제한적이다 :

추상 기계의 다른 측면 및 동작은이 표준에 명시되지 않았 음 (예 : 기능에 대한 인수 평가 순서)으로 설명된다. 가능한 경우,이 국제 표준은 허용 가능한 일련의 행동을 정의한다. 이것들은 추상 기계의 비 결정적 측면을 정의합니다. 따라서 추상 기계의 인스턴스는 주어진 프로그램 및 주어진 입력에 대해 둘 이상의 가능한 실행 순서를 가질 수 있습니다.

+0

'... 매개 변수화 된 비 결정적 추상 기계를 정의합니다. '추상 기계는 비 결정적이기 때문에 컴파일러의 단일 실행에서 동작이 일관성을 유지하는 것이 어떻게 필요합니까? –

+0

@Prasoon, 일부 경로 - 동작이 지정되지 않은 경로 만 비 결정 성을 도입합니다. 예를 들어, 정규 표현식'z (a | b)'는 입력이 끝날 때'a' 또는'b'와 일치하는 비 결정적 유한 상태 기계 (NFA)로 표현 될 수 있습니다. 그러나 여전히 입력의 시작 부분에서 'z'와 일관되게 일치합니다. 구현 정의 동작의 경우 매개 변수 (시작 부분에 'z')가 변경되면 다른 추상 기계가 생성됩니다. 더 이상 소스 코드를 번역하지 않고 하나만 구현하면됩니다. :) –

+0

아 !! 그리고 sharptooth의 질문에 따르면 입력 데이터가 '동일'해야한다고 언급되어 있습니다 .... 휴! thanks Johannes :) –

1

IIRC, system()이 필요하지만 구현 정의 동작이 있어야합니다. system ("ls | grep foo")과 같이 시스템이 ls라는 항목을 실행할 수 있는지 여부에 따라 자연스럽게 다른 효과가 발생합니다. ls는 실행마다 다를 수 있습니다. 그리고 ls와 grep이 당신이 기대하거나 수행하지 않는 UNIX 머신에서조차도 결과는 여전히 foo라는 이름의 파일이 존재하는지 여부에 달려 있습니다. 시간, 그리고 프로그램이 실행되는 곳 등이 포함됩니다. 단지 "동일한 입력 데이터"의 줄을 그리는 위치에 달려 있습니다. 기계가 완전히 똑같은 상태에 있다면 똑같은 동작을 기대할 수는 있지만 두 번의 실행에는 진정으로 pedantically 동일한 상태의 기계가 포함되지는 않습니다. (그렇지 않으면 완벽하게 동일한 시스템에서 CPU의 온도조차도 약간의 조절 동작을 유발하여 프로그램의 다른 동작을 눈에 보이는 결과로 만드는 경쟁 조건을 승자에게 바꾼다.)

3

내가 생각할 수있는 한 가지 예가 있습니다. 프로그램이 숫자에 대해 크거나 작은 엔디안 표현을 사용하는 경우 이것은 구현 정의 동작으로 간주 될 것입니다.

특정 ARM 칩과 같이 런타임에 모드를 전환 할 수 있으므로 어느 모드에서든 실행될 수있는 컴파일러가 필요하므로 구현이 정의 된 동작이 잠재적으로 다를 수 있습니다 각 실행마다 외부 설정에 따라

마찬가지로 나는 32 비트 64 비트를 동일한 프로그램으로 컴파일 한 컴파일러를 작성할 수 있다고 생각한다. 실행 된 모드는 런타임에 결정될 수있다. 다시 말하지만, 문서는 int가 32 비트 또는 64 비트 였다고 말할 수 있습니다.

솔직히 나는이 중 하나를 수행하는 사람을 볼 수는 없지만, 둘 다 묻고있는 것이 막연하고 그럴듯한 예를 들었고 왜 표준에서 오래 사용할 수 없는지 알 수 없습니다. 문서가 시스템 종속 동작의 성격을 적절하게 문서화했기 때문입니다.

+0

+1, MacOSX 유니버설 바이너리에는 32 비트와 64 비트 버전 (64 비트 지원이있는 최신 MacOS X 버전)이 포함되어 있으며 실행하려는 버전을 시작할 때 선택할 수 있습니다. 바이너리에는 PowerPC와 완전히 다른 아키텍처의 코드가 포함될 수도 있습니다. 궁금한 점이 있으면 유용합니다.64 비트에서 실행되지 않는 사파리 플러그인이 있으므로 필요할 때 32 비트에서 사파리 세션을 시작할 수 있습니다. –

+0

아아, 나는 MaxOSX가 이것을 한 것을 몰랐다. :) – jcoder

1

보장은 컴파일러가 문서화 한 것입니다. 컴파일 타임에 다른 컴파일러 플래그 또는 다른 상태가 컴파일러/최적화 프로그램이 프로그램을 처리하는 방법에 영향을 줄 수 있으며 결과에 영향을 미칠 수 있습니다. 컴파일러 플래그가 가장 큰 영향을 미칩니다 (동일한 컴파일러는 64 비트 환경에서 32 비트 및 64 비트 프로그램을 생성하는 데 사용될 수 있으며, 두 번의 실행에서는 정렬 요구 사항이 다를 수 있음).

대부분의 경우 구현자는 구현 및 컴파일러/링커 매개 변수 집합에 대해 생성 한 프로그램의 동작에 대해 몇 가지 기본적인 보장을 제공 할 것으로 기대할 수 있습니다. 시스템의로드가 옵티마이 저가 프로그램에서 작동 할 수있는 양에 영향을 줄 수 있더라도 일부 옵티마이 저는 제한된 시간이 할당되며 이는 예상되는 동작을 변경해서는 안됩니다.

보증은 없지만 관련없는 매개 변수에 따라 달이 별에 비해 상대적으로 다른 동작을하는 코드를 생성하는 컴파일러를 판매하는 것은 어렵습니다.