Just a curiosity. It appears that you can't define an external function with no arguments.

My answer to an exercise in Fortran 95, Martin Counihan, Section 7.2, Exercises 7.A, page 114, Exercise 7.A10.
"Using RANDOM [rather, RANDOM_NUMBER], write an integer function
that will simulate the throw of two dice, adding their results. If
a double is thrown, an extra throw is allowed in addition."

No arguments are needed, but the compiler requires that I put in an argument. Is this correct?

I seem to recall that when I programmed professionally (in the 1970's), I didn't use FUNCTIONs. I only used SUBROUTINEs and passed the results as arguments.

Paul: Here is the main program, which calls Function TwoDice:
WINAPP !for CLEARWIN
PROGRAM Main
USE CLRWIN$
!
! Fortran 95, Martin Counihan
! Section 7.2, Exercises 7.A, page 114
! Exercise 7.A10, a/k/a 7.Aa.
! This is file Ex.Aa_tst_Main.f95.
! This version tests not having any arguments.
!
! "Using RANDOM [rather, RANDOM_NUMBER], write an integer function
! that will simulate the throw of two dice, adding their results. If
! a double is thrown, an extra throw is allowed in addition."
!
! The function TwoDice returns a scalar, giving the total of the
! throw on two dice. This main program determines if doubles were thrown.
! I suspect that the function must have an argument.
!
! (This version doesn't have any arguments.)
!
IMPLICIT NONE
INTEGER, EXTERNAL:: TwoDice
INTEGER:: Tot, Total
!
MainLoop: DO !We will repeat this process indefinitely
Tot = TwoDice !Call the function - roll the dice
Total = ABS(Tot)
WRITE(*,*) "The total roll of the dice is: ", Total
Doubles: IF (Tot.LT.0) THEN
CYCLE MainLoop !Doubles, roll again
ELSE IF (Tot.GT.0) THEN Doubles
PAUSE !Not doubles, await operator response
CYCLE MainLoop
ELSE Doubles
STOP "How did we get here?"
END IF Doubles
END DO MainLoop
!
END PROGRAM Main

Compiling it in Plato, “Debug Win32” yields the following error in Errorlog:

C:\Kalish_data\FORTRAN source\95\Fortran 95 Counihan\ch07p114\Ex7.Aa_tst_Main.F95(26) : error 1168 - TWODICE is a routine name, and cannot be used in this context

and in Ex7.Aa_tst_Main.ERR:

C:\Kalish_data\FORTRAN source\95\Fortran 95
Counihan\ch07p114\Ex7.Aa_tst_Main.F95(26) : error 1168 - TWODICE is a
routine name, and cannot be used in this context
The same error results from compiling with ftn95.exe in command prompt.

The function isn't EXTERNAL, for a start, and when I produce a function and remove the EXTERNAL attribute, that error goes away. also add brackets to the call to get rid of the warning.

Code:

WINAPP !for CLEARWIN
PROGRAM Main
USE CLRWIN$
IMPLICIT NONE
INTEGER TwoDice
INTEGER:: Tot, Total
MainLoop: DO !We will repeat this process indefinitely
Tot = TwoDice() !Call the function - roll the dice
Total = ABS(Tot)
WRITE(*,*) "The total roll of the dice is: ", Total
Doubles: IF (Tot.LT.0) THEN
CYCLE MainLoop !Doubles, roll again
ELSE IF (Tot.GT.0) THEN Doubles
PAUSE !Not doubles, await operator response
CYCLE MainLoop
ELSE Doubles
STOP "How did we get here?"
END IF Doubles
END DO MainLoop
END PROGRAM Main
INTEGER FUNCTION TwoDice()
TwoDice = 1
END

Eddie, compiles fine with or without EXTERNL. It is the parethesis what was the issue.

And of course way too laconic error messages completely unacceptable for the novices. The guy is trying to run his first program ***for weeks***, isn't this a proof that compiler developers have to change? It is hard to express how I hated those compiler messages when I was just learning English and Fortran. And I started to hate them again as the difficulty to debug larger and larger codes grow exponentially.

Yesterday I also got one of such "elitist" messages: "Unknown variable", "This variable is illegal in this context" or something like that and was scratching my head for an hour trying to understand how I have to proceed to find a needle in the hive. I see the variable, debugger sees the variable, compiler did not complain about this variable, it was explicitly declared as usual so even John Campbell will not shirtfront me (like former Australian PM Tony Abbott tried with Putin) with his 'implicit none', still I got Access Violation and when debugged and hovered on variable with the mouse in SDBG the bubble message popped "Unknown Variable" )))

Found the error literally by mistake. In another place similar variable was called as if it was a function. Was it hard to add why compiler considered this variable as an illegal or unknown? Not enough RAM or harddrive space like in 1980th?

For novices and i'd say even for everyone besides probably total 1-2 people the more verbose error messages with the suggestions covering how typically such errors appear is what this compiler needs.

Last edited by DanRRight on Thu Oct 26, 2017 4:24 am; edited 1 time in total

The following is an example of using a FUNCTION without any arguments.
The use of EXTERNAL is optional.
Most timing functions do not require an option, or where the inputs are provided via COMMON or MODULE.
Arguments were once required, so "old" Fortran looks better without () call list.

Dan, John, I agree that the parentheses are the issue, but I reported what I found. EXTERNAL is indeed not the problem, but without it, the original error message goes away. If FTN95 reported warnings for everything, it would include warning No. XYZ1234 'EXTERNAL specified when FUNCTION name not used in a subprogram call'. FTN95 has several of these 'don't matter' things, like if a subprogram expects LOGICAL you can supply 0 or 1 or an integer variable.These things may matter decades hence.

Dan, I like the verb 'to shirtfront', but the needle is lost in a haystack, not a hive. One hopes not to find needles these days!

Eddie, looking for the needle in the bee hive would better resemble my everyday troubles with English and Fortran languages . As to diagnostics, does your compiler give the error message on EXTERNAL and warning on absent () ?

When I'm not using FTN95, I use the Holy_Grail compiler from Fantasy Land computer services, Camelot, near Stonehenge. It has the wonderful facility to compile what you intended, rather than what you wrote, and if you use the /c (change) switch, it changes the source code to suit. Moreover, as it was developed some time ago, it has none of the newfangled stuff, most of which is already there but in a different guise. It can detect common typing errors, accidental deletion of characters and so on, and with the /i (imagine) switch, it does such routine things as matching mismatched brackets, quotes, function and subroutine declarations and calls, and so on. Executable codes run at least 100x quicker than the fastest of the other compilers - and there are never any run time errors. It enforces strict compliance to the Fortran standard in use when it was developed (Merlin could only foresee 77) - unless you intended something else and it does that instead (with the /u for understood switch, of course). A final advantage - it stamps out devilry! (With the /e for exorcism switch).

Unfortunately, it doesn't support Clearwin+ and has no graphics - so for many practical purposes it is useless, and is why I use FTN95 for everything that matters.

Oh Drat! It was a serious question. Yes, when I knock out EXTERNAL the error message goes, leaving just the warning, which is removed when () are added in.

Eddie, I did not ask without the reason because the warning when you add external rise the suspicion that i am not alone influenced by the devilry if you confirm that your compiler is 8.10.

John, agree, let's return to Fortran:

Code:

!
! I do not know how media covered this in Australia,
! but it was big fun in the rest of the world to wait
! fistfight between PM and Putin and even bigger laugh
! when Putin came and nothing happened.
! PM's days after that were counted.
!

Still no good. It doesn’t seem to matter how I phrase the FUNCTION statement: FUNCTION TwoDice() or FUNCTION TwoDice give the same results. The problem is the main program. It never seems to call the function.

Compiling the main program yields the above-mentioned error about an undefined variable, array element or function result. If I compile with the /-FULL_UNDEF option, compilation gives a warning “C:\Kalish_data\FORTRAN source\95\Fortran 95 Counihan\ch07p114\Ex7.Aa_test_Main.F95(31) : warning 298 - Variable TWODICE has been used without being given an initial value”. The routines can be SLINKed and executed, but the main program never seems to call the function. None of the WRITE statements in the function are executed, and the value “returned” is -128, which is the value of an undefined INTEGER KIND=1.

Declaring a function without any arguments should not be a issue.
You must be doing something else unusual.

Try the following change to your posted code:

Code:

WINAPP !for CLEARWIN
PROGRAM Main
USE CLRWIN$
!
! Fortran 95, Martin Counihan
! Section 7.2, Exercises 7.A, page 114
! Exercise 7.A10, a/k/a 7.Aa.
! This is file Ex.Aa_tst_Main.f95.
! This version tests not having any arguments.
!
! "Using RANDOM [rather, RANDOM_NUMBER], write an integer function
! that will simulate the throw of two dice, adding their results. If
! a double is thrown, an extra throw is allowed in addition."
!
! The function TwoDice returns a scalar, giving the total of the
! throw on two dice. This main program determines if doubles were thrown.
! I suspect that the function must have an argument.
!
! (This version doesn't have any arguments.)
!
IMPLICIT NONE
INTEGER, EXTERNAL:: TwoDice
INTEGER:: Tot, Total
!
MainLoop: DO !We will repeat this process indefinitely
Tot = TwoDice () !Call the function - roll the dice
Total = ABS(Tot)
WRITE (*,*) "The total roll of the dice is: ", Total
Doubles: IF (Tot.LT.0) THEN
CYCLE MainLoop !Doubles, roll again
ELSE IF (Tot.GT.0) THEN Doubles
PAUSE !Not doubles, await operator response
CYCLE MainLoop
ELSE Doubles
STOP "How did we get here?"
END IF Doubles
END DO MainLoop
!
END PROGRAM Main