Passing a command-line real argument

Undoubtedly a stupidly simple thing that I am missing but I cannot find it referenced elsewhere.

I take in command line arguments to help set parameters in my model. One such argument is for a real value to be passed. This has the switch of -t

For example…

dummymain -t1
dummymain -t2
dummymain -t0.5

In my select case for all arguments I have these two lines for this switch:

                case ("-t", "-T")
                    read(argValue, *) fsolmass

However, passing in -t0.5 causes a segmentation failure.

How should I resolve this for all example instances?

More code is needed to be able to help you. In particular how argValue is declared and assigned.

I thought I had resolved this but now realise I was wrong.

So, the issue continues.

The variable declarations relevant to this are:

real(DP)         :: fsolmass
character(20) :: arg
character(2)   :: argAction
character(18) :: argValue

The whole select statement (so far) is…

if (command_argument_count() > 0) then
        do i = 1, command_argument_count()
            call get_command_argument(i, arg)
            argAction = arg(1:2)
            if (len(arg) > 2) then
                argValue = arg(3:len(arg))
            end if
            
            select case (argAction)
                case ("-a", "-A")
                    read(argValue, *) accmethod
                    
                case ("-b", "-B")
                    read(argValue, *) fburst
                    
                case ("-c", "-C")
                    read(argValue, *) corm
                    
                case ("-f", "-F")
                    read(argValue, *) filename
                
                case ("-h", "-H")
                    call get_help()
                    stop
                    
                case ("-m", "-M")
                    massonly = .true.
                    
                case ("-s", "-S")
                    read(argValue, *) steps
                    
                case ("-t", "-T")
                    read(argValue, *) fsolmass
                    
                case default
                    print '(a,a,/)', 'Unrecognized CL option: ', argAction
                    call get_help()
                    stop
            end select
        end do
    end if

With the -t/-T option being the issue.

I thought this was a casting issue, but integer values work in all the above instances, including for fsolmass. If I put -t1 or -t2 then all works fine. However, if I put -t0.5 it fails.

DP is defined as integer, parameter :: DP = kind(0d0)

I think that is everything.

I have reproduced your code, just removing all cases but the -t one, and it works just fine: Compiler Explorer

Are you using debug switches that point to the line parsing the value and/or getting a traceback that indicates the segfault occurs at the READ? It is unusual to get a segfault with such a statement if the character variable is defined. So one question is do you know the segfault occurs during parsing or is it later? Another is that some compiler versions have bugs with using list-directed I/O on an internal read; so which compiler and version are you using?

Segfaults can be caused by overwriting memory in a totally different part of the code, and that is likely an issue here, but if you print the value of argValue before reading from it that could help; as in

case("-t","-T")
write(*,*)'ARGVALUE=',argValue
read(argValue, * ) fsolmass
write(*,*)'FSOLMASS=',fsolmass

Are you getting a traceback or debug statement that indicates a linenumber where the error causes the seg fault?

I don’t know if this is your problem, but there appears to be a minor conceptual error in this section of code. The len(arg) expression is a constant within this loop, the value depends on the declared length of arg, not its value. I don’t think that is what you want. Instead, you should modify the first line to something like

call get_command_argument(i, arg, length=lenarg)

where lenarg is declared to be an integer variable. Then use that value in the if() statement and the subsequent assignment rather than len(arg). There is also an optional status= argument where you can test for truncated arguments that might be useful in this case. As noted previously, simply printing out the values of lenarg, arg, and argValue might show what is the problem.

However, I don’t really think this conceptual error is causing your problems. It looks to me like your code should have worked alright in the first place with the argument you gave it because of the way fortran fills in blanks while fetching the argument values and with the assignments.

1 Like

Thank you.

No. My issue was greater than this; far greater. :frowning: