이 앱을 다운로드했습니다2D 구축GNU Fortran을 사용하여 컴파일합니다 gfortran 9.3.0
. gnu make를 사용하여 이 프로그램을 컴파일할 수 있습니다:
make
(컴파일 시간: GNU bash를 사용하여 Ubuntu 20.04 버전 5.0.17(1) 릴리스(x86_64-pc-linux-gnu)를 실행하는 PC에서 10초).
프로그램은 매개변수와 함께 작동하지 않으며 대신 옵션을 수동으로 입력해야 합니다. 지루한 작업 흐름을 피하기 위해 옵션을 파일에 기록합니다 instructions.txt
.
construct2d < instructions.txt
그 내용은 instructions.txt
다음과 같습니다:
naca0012.dat
SOPT
NSRF
80
RADI
5
NWKE
5
QUIT
VOPT
JMAX
5
YPLS
5
RECD
1E5
QUIT
GRID
SMTH
QUIT
파일은 naca0012.dat
압축되지 않은 Construction2D 아카이브 디렉토리에서 찾 sample_airfoils
거나 여기에서 다운로드할 수 있습니다.협회.
문제는 다음 명령입니다.
construct2d < instructions.txt
한 번만 실행하면 예상한 결과가 나오지 않습니다. 예상 결과를 얻으려면 위 명령을 여러 번(아마도 4번) 실행해야 합니다. (예상 출력은 다음과 같습니다. naca0012.p3d
및 naca0012.nmf
)
수동으로 실행하고 construct2d
옵션을 하나씩 입력하면 예상대로 작동합니다. 이를 디버깅하기 위해 instructions.txt
사용해 보았지만 불행하게도 특별한 내용은 표시되지 않습니다.gdb
따라서 프로그램이 파일에서 일부 지침을 제공할 때 일부 지침을 무시하는 것 같습니다. 왜 이런 일이 발생합니까?
프로그램이 예상대로 실행될 때 stdout 출력(추가로 프로그램은 출력 파일
naca0012.p3d
및naca0012.nmf
)을 생성합니다.작업일지프로그램이 예상대로 실행되지 않을 때의 표준 출력(출력 파일 없음):작동하지 않는 로그
당신의 도움에 정말 감사드립니다.
편집 1:
Windows 10에서는 gfortran 8.1.0을 사용하면 파일 리디렉션이 실패 없이 잘 작동합니다. 위에서 설명한 것처럼 이는 Linux에서만 발생합니다.
편집 2:줄 끝과 관련이 없음을 확인합니다. Linux에서 파일 자체를 만들었기 때문입니다 instructions.txt
. 도구를 사용하여 dos2unix
파일을 검사합니다.
편집 3 이전 버전의 gfortran(Ubuntu Server 18.04의 gfortran 7.5.0)을 사용하여 프로그램 컴파일을 시도했는데 모든 것이 잘 작동했습니다. 이는 GNU Fortran 최신 버전의 버그일 수 있습니다.
편집 4:
플래그를 추가하거나 -Og
프로그램 을 컴파일할 때 -O0
gfortran 9.x 및 10.x의 이상한 동작을 해결했습니다 .
답변1
comp.lang.fortran의 기여자:
한 가지 문제는 메인 루프의 위치인 것 같습니다.
done = .false.
do while (.not. done)
call main_menu(command)
call run_command(command, surf, options, done, ioerror)
end do
"run_command"를 호출하십시오:
subroutine run_command(command, surf, options, done, ioerror)
...
logical, intent(out) :: done
integer, intent(inout) :: ioerror
gfortran은 "run_command"가 "done" 값을 사용하지 않기 때문에 실제로 "done = .false" 문을 실행하는 데 아무런 의미가 없다고 추측하는 것 같습니다. 그리고 "run_command"는 "quit" 명령을 확인하지 않는 한 인수 "done"을 실제로 아무 것도 설정하지 않기 때문에 메인 루프가 "done"을 확인하는 동안 "done"은 초기화되지 않은 상태로 유지됩니다. 때로는 거짓일 때도 있고, 쓰레기를 포함할 때도 있는데, 이 경우 참으로 평가되어 메인 루프가 일찍 종료됩니다.
"done"의 의도를 "inout"으로 변경하면 문제가 해결되는 것 같습니다.
run_command의 "select case" 문 앞에 "done"을 설정하는 것도 작동하는 것 같습니다.
done = .false.
select case (command)
...
내 생각에는 이것이 이 문제를 해결하는 올바른 방법이며 컴파일러의 동작은 나를 포함하여 우리 중 일부에게는 놀랍지만 실제로는 정확하다고 생각합니다.
valgrind가 이것을 찾는 데 도움을 주었습니다.
또 다른 포스터는 다음과 같습니다.
마찬가지로 다음 예는
type(options_type), intent(out) :: opt
menu.f90 파일에서 다음으로 변경되어야 합니다.
type(options_type), intent(inout) :: opt
또는 Intent(out)가 있는 인수는 서브루틴에 들어갈 때 정의되지 않고 반환하기 전에 서브루틴에서 값을 가져오지 않으면 정의되지 않은 상태로 유지되므로 Intent 절을 생략해야 합니다.
다른 제안에는 배열 경계를 확인하는 옵션 등을 사용한 컴파일 및 실행이 포함됩니다.
답변2
이전 버전의 gfortran(gfortran 7.x 및 8.x)을 사용하여 프로그램 컴파일을 시도했는데 모든 것이 잘 작동했습니다. 그러나 최신 버전의 gfortran(9.x 및 10.x)에는 여전히 이 문제가 있습니다. 그런데 gfortran 9.x와 10.x에서 발생하는 이상한 동작을 플래그를 추가하거나 프로그램을 컴파일할 때 해결했습니다 -Og
.-O0
@RoboNerd의 답변은 처음에 이런 일이 발생하는 이유를 설명합니다.