3

I've downloaded this program construct2d and compiled it using GNU Fortran gfortran 9.3.0. You can compile the program using gnu make:

make

(compilation time: 10 seconds on my PC running Ubuntu 20.04 with GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu) ).

This program doesn't work with arguments, instead I have to enter manually the options. In order to avoid that tedious workflow I wrote the options in a file instructions.txt to feed it.

construct2d < instructions.txt

The content of instructions.txt is:

naca0012.dat
SOPT
NSRF
80
RADI
5
NWKE
5
QUIT
VOPT
JMAX
5
YPLS
5
RECD
1E5
QUIT
GRID
SMTH
QUIT

The file naca0012.dat can be found under sample_airfoils directory from uncompressed construct2D archive or can be downloaded from this link.

The problem is that the command:

construct2d < instructions.txt

doesn't give the expected result when I run it only once, I have to run the command above several times (4 times maybe) to get the expected results: (the expected output is: naca0012.p3d and naca0012.nmf).

When I run construct2d manually and type the options in instructions.txt one by one, it works as expected. I've tried to use gdb to debug that but unfrotunately it doesn't show anything special.

So it appears that the program is ignoring some instructions when feeded from a file. Why does this happen?

  • The stdout output when the program runs as expected (in addition, the program will generate the output files: naca0012.p3d and naca0012.nmf): working.log

  • The stdout output when the program doesn't run as exepcted (without output files): not_working.log

I greatly appreciate your help.

EDIT 1:

On Windows 10, with gfortran 8.1.0, file redirection works just fine, it doesn't fail. This happens only on Linux as I described above.

EDIT2: I confirm this has nothing to do with line endings. Because I've created the file instructions.txt itself on Linux. And used dos2unix tool to check the file.

EDIT3 I have tried compiling the program with older versions of gfortran (gfortran 7.5.0 on Ubuntu server 18.04) and everything works correctly. This might be a bug in newer versions of GNU Fortran.

EDIT 4:

I've solved that weird behaviour in gfortran 9.x and 10.x by adding the flag -Og or -O0 when compiling the program.

6
  • @user414777: I have tried cat but unfortunately it has the same behaviour as file redirection. Sep 16 '20 at 17:38
  • @user414777: I've also tried script -c ... but it is the same thing again. Sep 16 '20 at 17:41
  • @user414777: I made sure running dos2unix on those file even I created it on Linux Sep 16 '20 at 22:46
  • 1
    Sorry, I've tried to reproduce it, but I wasn't able to. construct2d < instructions.txt (with instructions.txt copy-pasted from your answer) does work fine and generates those two files. I have Debian 10, GNU Fortran 8.3.0, and I had compiled the program from source as in your question.
    – user414777
    Sep 16 '20 at 23:19
  • @user414777: Thanks! I suspect it is due to the compiler itself, I will install an older compiler and see the result. Sep 17 '20 at 5:37
1

From contributors to comp.lang.fortran:

One problem seems to be where the main loop:

  done = .false.
  do while (.not. done)

    call main_menu(command)
    call run_command(command, surf, options, done, ioerror)

  end do

calls 'run_command':

subroutine run_command(command, surf, options, done, ioerror)
  ...
  logical, intent(out) :: done
  integer, intent(inout) :: ioerror

gfortran seems to be guessing that since the value of 'done' is never used by 'run_command', there's no point in actually executing the statement 'done = .false.' and since 'run_command' doesn't actually set its argument 'done' to anything unless it sees a 'quit' command, 'done' is left uninitialized when the main loop checks it. Sometimes it's false, and sometimes it contains garbage, in which case it's evaluated as true and the main loop terminates early.

Changing the intent of 'done' to 'inout' seems to fix the problem.

Setting 'done' before the 'select case' statement in run_command also seems to work:

  done = .false.

  select case (command)
  ...

My guess is that this is the right way to fix this, and that the compiler's behavior, while surprising to some of us (including me), is in fact correct.

valgrind helped find this.

And from another poster:

Along the same lines, the several instances of

type(options_type), intent(out) :: opt

in file menu.f90 should be changed to

type(options_type), intent(inout) :: opt

or the intent clause should be left out, because an argument with intent(out) becomes undefined when the subprogram is entered and stays undefined unless it acquires a value in the subprogram before returning.

Other suggestions included compiling and running with options to check array bounds, etc.

2

I have tried compiling the program with older versions of gfortran (gfortran 7.x and 8.x) and everything works correctly. But the issue persist with newer versions of gfortran (9.x and 10.x). However, I've solved that weird behaviour in gfortran 9.x and 10.x by adding the flag -Og or -O0 when compiling the program.

The reason why this happens in the first place is explained in the answer of @RoboNerd.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.