I'm trying to get some code compiled under gfortran that compiles fine under g77. The problem seems to be from a return statement:
ffuncs.f:934.13:
RETURN E
1
Error: Alternate RETURN statement at (1) requires a SCALAR-INTEGER return specifier
In the code anything E was specified as real*8:
IMPLICIT REAL*8 ( A - H , O -Z )
However, E was never given a value or anything in fact you never see it until the return statement. I know almost nothing about fortran. What is the meaning of a return statement with an argument in fortran?
Thanks.
In FORTRAN (up to Fortran 77, which I'm very familiar with), RETURN n is not used to return a function value; instead, it does something like what in other languages would be handled by an exception: An exit to a code location other than the normal one.
You'd normally call such a SUBROUTINE or FUNCTION with labels as arguments, e.g.
CALL MYSUB(A, B, C, *998, *999)
...
998 STOP 'Error 1'
998 STOP 'Error 2'
and if things go wrong in MYSUB then you do RETURN 1 or RETURN 2 (rather than the normal RETURN) and you'd be hopping straight to label 998 or 999 in the calling routine.
That's why normally you want an integer on that RETURN - it's not a value but an index to which error exit you want to take.
RETURN E sounds wrong to me. Unless there's a syntax I'm unaware of, the previous compiler should have flagged that as an error.
In a Fortran function one returns the value, by assigning the value to a fake variable which is the same name as the function. Once you do that, simply return.
I think #Carl Smotricz has the answer. Does argument list of ffuncs has dummy arguments that are asterisks (to match the asterisk-label in the calls)? Or was this used without there being alternative returns? If there were no alternative returns, just delete the "E". If there are alternative returns, the big question is what the program was doing before at run time since the variable was of the wrong type and uninitialized. If the variable didn't have an integer value matching one of the expected branches, perhaps the program took the regular return branch -- but that's just a guess -- if so, the easy fix is to again to delete the "E".
The "alternate return" feature is considered "obsolescent" by the language standard and could be deleted in a future standard; compilers would likely continue to support it if it were removed because of legacy code. For new code, one simple alternative is to return an integer status variable and use a "select case" statement in the caller.
Related
I'm very new at Fortran. I'm trying to compile this Fortran, I think 90??? Code. I'm using visual studio with the intel compiler.
The following code is giving me an error 5082. I have absolutely no idea why. Like literally no clue. Please, please help.
integer function Dub(n)
integer n
Dub = 2*n
return
end
program Subroutines
implicit none
! Variables
integer n
n = 5
! Body of Subroutines
write(*,*) n
Dub(n)
write(*,*) 'Press Enter to Exit'
read(*,*)
stop
end program Subroutines
In Fortran a call to a function, or a subroutine, must be part of a statement (or an initialization expression, but that's more advanced). name(argument[s]) by itself is not a statement, unlike some other languages such as C, C++ and Java. A function call must be in an expression, and a subroutine call must use the call keyword. See https://en.wikibooks.org/wiki/Fortran/Fortran_procedures_and_functions for examples.
Changing that line of your program to n = Dub(n) would make it legal, but rather useless. That function does nothing except return a value, and your main program does nothing useful with the value returned. Generally you call a function because you want either a side effect from executing the function, or to use the returned value, or both.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
Can anyone please explain the difference between return 0 and -1 used in c++? I have read many articles and posts from other programmers saying that return 0 means the program is successful and -1 means the program has an error. But what I don't get is why use these statements when the compiler will generate an error if there is one in the program anyway? Please explain in detail what these statements really mean.
This has absolutely nothing to do with the compiler.
The compiler will report syntax errors.
The return codes are used to report if the program completed successfully.
("Success" depends on what the program was intended to do).
For example:
// Program SearchTerm "term to find"
int main(int argc, char* argv[])
{
bool search_successful = false;
[ ... do work ... ]
if (search_successful)
{
return 0; // The search worked.
}
else
{
return -1; // The search failed
}
}
Example usage:
SearchTerm "Microsoft"
More than 1 million results found... returned Success
SearchTerm "asldfjpu"
No results found... returned Failure
When a program reports success or failure, it can be integrated in the Scripts such as:
#!/bin/bash
if `SearchTerm "Microsoft"`; then
GetTopResults "Microsoft"
else
echo "No results found, no Top Results to retrieve"
fi
The return value of int main() is the so called exit code of the program. This is already so in C (which has no exceptions) and is there to basically tell to caller how it went. A exit code of zero means success and every other exit code (but normally one uses only positive ones) means that something went wrong. Sometimes programms will document what a certain exit code means i.e. if a file was not found or an allocation failed etc.
This is a very important part of scripting for example bash scripts, which know in this way if a called command went right or wrong. Even if your program crashes with an exception, the programm will generate an exit code (which will be non-zero). In bash you can see the exit code of the last run program with echo $?, so you can check that out for yourself.
A return is simply the value returned by any function. At the end of a function, the computer is able to accept a single value to take back with it when it returns to the rest of the program. In the case of the function int main(), with which you are probably familiar, the return value is used as an indication of the success of the program.
main() is simply the entry point of the program you are running. It's the first function called by your computer when the program starts (with some exceptions)
Theoretically, you could return any integer from main().
The only "accepted" thing is that anything that is non-zero is generally some error or fault. So a return 0; indicates success, while return -1; might indicate some kind of error. The truth is, the value returned from main() doesn't really matter, and won't affect how your program runs.
If you're asking about the value returned by main, there are two defined values that you can return: EXIT_SUCCESS and EXIT_FAILURE. Those values are defined in the header <stdlib.h> and in the header <cstdlib>. You can also return the value 0, which is equivalent to returning EXIT_SUCCESS. There are no other meaningful values in C or C++, although your implementation can provide meanings for other values.
I am assuming that you are returning 0 or -1 from the main program as your program exits. What this does is inform the calling program the success or failure of the program. This is not very handy if you just run the program at a command prompt but if your program is called within a script (Perl,PHP, python, PowerShell, etc) you can test to see if the program was successful.
In a nutshell, if your program is called by another program, the calling program can test for success or failure and respond appropriately.
the program is successful and -1 means the program has an error.
Please explain in detail what these statements really mean.
There are situations where a function cannot proceed further, and cannot complete the task that it is specified for it. Such situation is typically called an error. There are many possible sources of errors. One example of that is a function that has pre-conditions for the inputs that were not satisfied by the caller of the function. An example of such pre-condition is square root function that calculates rational numbers (i.e. not complex): There is no result for negative input.
When an error is encountered, it must somehow be communicated to the caller. There are many techniques, but we shall not cover all of them in detail here. I'll mention that one option in C++ is exceptions. Exceptions technique has some useful properties, but it is not universally applicable to all situations.
Another, very simple technique is to return an error code which is an integer value. If we choose 0 to signify no error, the caller of the function can check for error with following pattern:
int error = function(arguments)
if (error) {
// handle error here
}
This pattern is very common in C APIs. C++ inherits C standard library, and it is common to take advantage of C libraries so it is common to encounter this in C++ as well.
Sometimes, a function needs to use the return value for some other purpose. For example, the open call from POSIX standard returns an integer called "file descriptor", which is a positive integer. Since some of the values in the domain of the return type are not used (negative numbers), it can be used to represent error condition as well. Although any negative number is available, -1 was chosen, and this is also quite conventional. In some other APIs different negative numbers represent different errors. Another approach is to store error information elsewhere. The chosen approach in POSIX is to store the error code in a separate variable.
In conclusion: Integer return values are a technique of communicating errors, and 0 is conventionally used to represent success and -1 is often used to represent erroneous execution. The meaning of the return value of a function should be documented by the implementer, and the documentation should be studied carefully by the user of the function.
But what I don't get is why use these statements when the compiler will generate an error if there is one in the program anyway?
It's unclear what you expect here. The compiler cannot read the programmer's mind and know all cases where the program should have an error. It can only tell whether the program is well-formed or not (and maybe give some helpful warnings about obvious mistakes if you're lucky).
It is the programmer's responsibility to consider the error conditions of the program.
The only difference between 0 and -1, as far as the compiler is concerned, is that they are two different numbers. Nothing is assumed whatsoever about their "success" or "failure" status (except in main in which the return value is ignored anyway).
The rest are (mostly bad) conventions used by developers. Usually < 0 for failure and 0 for success and you have created a nice bug when you test against bool (in which -1 is true and 0 is false).
One should use enums or, at least, something more recognizable as in windows HRESULT.
It basically means that anything other then 0 means something bad happened during execution of your program. The program could not deal with it so it exited with the status code.
Often when working with shell you will notice that some of commands exit with non 0 status code. You can check that value by running echo $? command.
And finally you can use return codes to communicate to the client what happend. That is if you describe what return codes can your program return.
I have been learning Lua from http://www.lua.org/pil/4.3.1.html and they had this piece of code:
if line > MAXLINES then
showpage()
line = 0
end
I don't understand what "showpage()" does here. I don't know whether this is just an example of a function that had to be previously defined (and I don't know if you can actually do this with a function) or is it a library I don't know of.
showpage is not a standard Lua function. You can find any of Lua's built-in functions in the Lua reference manual.
If you don't find a function there it is user-defined. You'll learn how to define functions in chapter 5.
It is indeed necessary that showpage is defined befor you call it. Otherwise you will face an error message for calling a nil value.
You'll find that many code examples skip the definition of some variables.
if a<0 then a = 0 end
if a<b then return a else return b end
if line > MAXLINES then
showpage()
line = 0
end
In this example a, b, showpage, line and MAXLINES are all nil. All of this would cause errors as you're neither allowed to call nil values nor to compare nil values with numbers.
Not sure if the authors were lazy, wanted to reduce the page count or intended to make you to think about their code.
I am asking user to give a value at run time to do some calculations.
I want to test if the user entered value is a real/integer number, and if not then give a warning that the program is expecting a real/integer number here.
In addition, I would as well like to know how do we check if a particular variable at the moment is null or empty. i.e. I have declared a variable but what if at the time of calculation its value is null or empty or not yet set, in that case, the program shouldn't crash instead give a warning to provide a correct value.
Both these operations are much more easier in C++ and C#, but I couldn't find a way to do that in Fortran.
I guess that "null or empty" you mean whether a variable has been initialized: "not yet set". "null" has a particular meaning for Fortran pointer variables, but I suppose that this is not your question.
Fortran doesn't automatically give variables a special value before they are intentionally initialized so there is no easy way to check whether a variable has been initialized. One approach is to initialize the variable its declaration with a special value. That means that you need to know a special value that it will never obtain in the operation of the program. One possibility is to use the huge intrinsic:
program TestVar
real :: AVar = huge (1.0)
if ( AVar < huge (1.0) ) then
write (*, *) "Test 1: Good"
else
write (*, *) "Test 1: Bad"
end if
AVar = 2.2
if ( AVar < huge (1.0) ) then
write (*, *) "Test 2: Good"
else
write (*, *) "Test 2: Bad"
end if
end program TestVar
As warned by #arbautjc, this only works once, even in a subroutine. In a procedure, the initialization with declaration is only done with a first call. Also, if you change the variable type from this example, be sure to understand how huge works (e.g., Long ints in Fortran).
Hello everyone I'm currently implementing a simple programming language for learning experience but I'm in need of some advice. Currently I'm designing my Interpreter and I've come into a problem.
My language is a subset of C and I'm having a problem regarding the stack interpreter implementation. In the language the following will compile:
somefunc ()
{
1 + 2;
}
main ()
{
somefunc ();
}
Now this is alright but when "1+2" is computed the result is pushed onto a stack and then the function returns but there's still a number on the stack, and there shouldn't be. How can I get around this problem?
I've thought about saving a "state" of the stack before a function call and restoring the "state" after the function call. For example saving the number of elements on the stack, then execute the function code, return, and then pop from the stack until we have the same number of elements as before (or maybe +1 if the function returned something).
Any ideas? Thanks for any tips!
Great question! One of my hobbies is writing compilers for toy languages, so kudos for your excellent programming taste.
An expression statement is one where the code in the statement is simply an expression. This means anything of the form <expression> ;, which includes things like assignments and function calls, but not ifs, whiles, or returns. Any expression statement will have a left over value on the stack at the end, which you should discard.
1 + 2 is an expression statement, but so are these:
x = 5;
The assignment expression leaves the value 5 on the stack since the result of an assignment is the value of the left-hand operand. After the statement is finished you pop off the unused value 5.
printf("hello world!\n");
printf() returns the number of characters output. You will have this value left over on the stack, so pop it when the statement finishes.
Effectively every expression statement will leave a value on the stack unless the expression's type is void. In that case you either special-case void statements and don't pop anything afterwards, or push a pretend "void" value onto the stack so you can always pop a value.
You'll need a smarter parser. When you see an expression whose value isn't being used then you need to emit a POP.
This is an important opportunity on learning optimization. you have a function that does number but integer math, the int math result isn't even used in any way, shape, or form.
Having your compiler optimize the function away would reduce alot of bytecode being generated and executed for nothing!