2014-09-08 1 views
12

저는 C++을 가르치기 시작했습니다. 다른 언어에서 온 것입니다. 나는 (학생) 파일로 작성된 API를 일관되게 검사 할 수있는 방법이 있었으면 좋겠다. 헤더의 완결성

학생이 파일을 제출한다고 가정

사실
// this is stu.cpp 
#include <iostream> 
using namespace std; 
double x(int y) {return y+0.5;} 

, 내가 다른 함수를 정의하는 학생에게 물었다 가정 INT X (INT). 이 코드를 실행하여이를 확인할 수 있도록하고 싶습니다 :

// this is stu.h 
int x(int); 

// this is gra.cpp 
#include "stu.h" 
#include <iostream> 
using namespace std; 

int main() { 
    cout << x(0); // test their code 
} 

그래서 학생의 구현이 필요한 인터페이스를 일치 있는지 확인하기 위해 노력하고, 내가 기대 한 것 입력 0에서 테스트하고

이없는 것 엮다. 내가

g++ -Wall -Wconversion *.cpp -o gra 
./gra 

을 할 때 그것은 컴파일 및 I 별도로 두 개의 파일을 컴파일 한 후이를 연결하는 경우에도이 사실로 남아 출력 0을주고, 충돌없이 실행됩니다.

나는 nm에 반환 유형을 나열하지 않는다는 것을 알고 있습니다. 반환 값이 일치하지 않을 때 두 파일을 함께 연결할 수있는 동일한 이유가 있습니까? 이것을 시험 할 정상적인 방법이 있습니까? (컴파일 타임 형식의 어설 션이 있습니까?)

int와 double이 서로 변환 될 수 있기 때문에이 특정 버그입니까? 이것을 잡을 수있는 더 많은 컴파일러 옵션이 있습니까?

// this is gra.cpp 
#include "stu.h" 
#include "stu.cpp" 
#include <iostream> 
using namespace std; 

int main() { 
    cout << x(0); // test their code 
} 

을 물론의 gra.cpp 컴파일 :

+3

'stu.cpp'에'stu.h '가 포함되면 오류가 발생합니다. –

+2

그래,'-Wall -Werror -Wextra'로 컴파일하고, 학생들에게 구현할 헤더 파일을 주어야합니다 ('# include '포함). –

+0

당신은'g ++ -flto -Wall -Wconversion * .cpp -o gra' 시도 할 수 있습니다. –

답변

8

학생 코드를 별도로 컴파일하는 대신 테스터 프로그램에 직접 포함시키지 않으시겠습니까?

int x(int); 
#include <stu.cpp> 

그리고이 같은 좋은 오류가 발생한다 :

a.cpp:2:8: error: functions that differ only in their return type cannot be overloaded 

을이 학생의 코드를 컴파일 할 수있는 "일반적인"방법은 아니지만, 코드가 확인 될 수 있음을 보장한다.


다른 방법으로는 학생의 C++ 파일을 컴파일 할 때 원하는 API를 포함하는 헤더 파일을 포함하도록 컴파일러에 강제로 -include (GCC, 연타) 같은 컴파일러 명령 줄 옵션을 사용할 수 있습니다. 예를 들어 :

api.h

int x(int); 

g++ stu.cpp -include api.h 컴파일하고 해당 오류가 발생합니다.

+1

심볼 재 정의와 같은 오탐 (false positive)이 발생할 수 있습니다. –

+0

@OliCharlesworth : 이유가 무엇입니까? 첫 번째 해법은'stu.cpp'를 변형 시키므로'stu.cpp'는 독립적으로 컴파일되지 않습니다. 두 번째 솔루션은 그레이더 (grader) 선택의 헤더 만 주입합니다.이 헤더에는 함수 프로토 타입 만 포함되어야합니다. 심볼 재정의 오류가 발생하는 곳을 볼 수 없습니까? – nneonneo

+0

함수 포인터를 사용하여 삭제 된 또 다른 해답이있었습니다. 특히, 학생이 편평한 방법을 정의하지 않고 건너 뛰었을 때 쉽게 확인할 수 있기 때문에 꽤 우아한 함수 포인터를 사용했습니다. 이 방법을 사용하면 메서드가 정의되지 않은 경우 오류를 발생시키는 방법이 있습니까? 나는 C++이 자동적으로 무대 뒤에서 많은 타입들을 변환 할 것이기 때문에 "그냥 호출 해보자"는 것은 항상 효과가 없을 것이라고 우려한다. – daveagp

1

는 다음과 같은 작업을 수행 할 수 있습니다.