gfortran open error messages - fortran

I seem to remember the open in gfortran has the possibility to return the result of iostat as a string, but I have forgotten the option name to return the string.
Does anybody remember the parameter to use?

From ftp://ftp.nag.co.uk/sc22wg5/n1551-n1600/n1579.pdf:
IOMSG= specifier: Any input/output statement is permitted to have an
IOMSG= specifier. This identifies a scalar variable of type default
character into which the processor places a message if an error,
end-of-file, or end-of-record condition occurs during execution of the
statement. If no such condition occurs, the value of the variable is
not changed.

Related

When the control flow off the end of a function without a return, why there is still a returned value?

#include <iostream>
int func(int &a,int &b){
if (a>b){
return 1;
}
}
int main(){
int a=4,b=12;
std::cout<<func(a,b)<<std::endl;
}
I think a run time error should occur because a is smaller than b, and the return statement is skipped. But it actually outputs the value of b no matter how I change the value of b. Could you please tell me why?
it should detect a run time error
That is not the case. The behaviour is undefined.
It seems to be related the value of b, why is that happening?
Because the behaviour is undefined.
This is happening because a result of functions (if the return type is int) is transferred using rax register of CPU. return keyword places its argument in this register and returns to the caller function. But there is also an implicit return keyword at end of any function in C/C++ (if there is no explicit return placed by a programmer). And this is why this function returns control flow to the caller function.
But contents of rax register should be treated in this case as random because the compiler can use it for any variable or even totally ignore it.
Falling out of a non-void function without returning is undefined behaviour, there's nothing your program or the runtime "should" do in that case.
You should not suppress the compiler warnings!
gcc says:
main.cpp:35:1: warning: control reaches end of non-void function [-Wreturn-type].
As others already mentioned: Your program has UB! So read the warnings and fix your program accordingly!
it should detect a run time error
And there is no need for run-time error, as the error is visible during compile-time! The core language has no run-time errors at all. If you see some error messages during program execution, it is coming from library code like a called "terminate" from an exception or something else.
It is good to have all the warnings enabled and also sometimes helpful to run different compilers over the code to get most of warnings possible.
For gcc you could add:
-Wall -pedantic -Wextra
That enables a lot of warnings, but not all. There are still some warnings which are not addressed like: -Wsuggest-override
In C++ if a function is declared to return a value but it doesn't, it is undefined behavior

Default behavior of OPEN with STATUS='NEW'

I am compiling a program (that I did not write) using gfortran. The make file specified f77 as the compiler, but I do not have it.
I have run into an error related to the OPEN command.
Error: The STATUS specified in OPEN statement at (1) is 'NEW' and no FILE specifier is present
I looked into Fortran 77 OPEN, and according to the Oracle language reference there is a default behaviour when 'FILE=name' is not specified.
http://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vnaf/index.html
'NEW' -- The file doesn't exist (existence is an error). If 'FILE=name' is not specified, then a file named 'fort.n' is opened, where n is the specified logical unit.
Is there a way to force the compiler to use the language specified default behaviour. Alternatively, can I modify the code to perform the expected default behaviour?
The document you cite is not a language specification, it is a description of one particular compiler. The behaviour regarding the file fort.n is compiler specific. For actual standard documents see https://stackoverflow.com/tags/fortran/info
Specifically, the Fortran 2008 says:
9.5.6.10 FILE= specifier in the OPEN statement
1 The value of the FILE= specifier is the name of the file to be connected to the
specified unit. Any trailing blanks are ignored. The file-name-expr
shall be a name that is allowed by the processor. If this specifier is
omitted and the unit is not connected to a file, the STATUS= specifier
shall be specified with a value of SCRATCH; in this case, the
connection is made to a processor-dependent file. The interpretation
of case is processor dependent.
That means that your program is not conforming, because when FILE= is omited, the only permissible value of STATUS= is "SCRATCH".
Gfortran also does create the fort.n files when you write to a unit which you did not open, but not when you execute the open statement with status="new". It should be easy for you to add the file= specifier to the code. You can even use the fort.N names if you insist on them. See Convert integers to strings to create output filenames at run time for the way how to get the integer into the file name.
Another option is to download the Oracle Solaris Studio, it contains the f77 command and is likely to follow the compiler specific document you have cited. It is actually quite a good compiler (if lacking some modern Fortran features) with very good visual debugging and profiling utilities. However, I recommend you to make your code portable and standard conforming first.

Type * error in gfortran

When I run my code I get the following error for all the statements that have the following format. Is there any problem with the type statement? If yes kindly provide me with a solution. I running my code on a Ubuntu 14.10 system. The program is very long hence I am not posting it now however if required I can surely send it.
recfunk_ascii.f:622.12:
type *,'enter back-azimuth limits ib1,ib2 (integers!)'
1
Error: Invalid character in name at (1)
Type is an obsolete and completely non-standard statement (see http://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vnbi/index.html). It is not portable because many compilers do not recognize it. It should be changed to a PRINT statement, as #francescalus suggest in the comment.
print *,'enter back-azimuth limits ib1,ib2 (integers!)'

what is the use of "static_cast<void>" in macro?

I'm seeing a macro definition like this:
#define ASSERT_VALID_PARAM(param, assertion) { static_cast<void>(param); if (!(assertion)) { throw InvalidParamError(#param, #assertion, __FILE__, __PRETTY_FUNCTION__, __LINE__); } }
I'm not able to figure out the need of static_cast<void>(param) here.
Any idea on why this is needed?
This macro is designed to validate a certain real parameter passes a certain validation rule(s). The logic part of the macro is composed of 2 parts:
Validate that param is a real parameter, with a valid name. This is done by using the static_cast, and if an illegal name is used, a compile time error will be generated.
Validate the "truthyness" of assertion. This is done with a simple negating if statement.
If the param is a valid name, and the assertion fails (assertion == false), an InvalidParamError is thrown, using the passed in parameters as strings (using the Stringizing operator #) to initialize the error object.
Since the actual usage of the param parameter in the macro is only as a string, it has to be validated using actual code. Since no real operation is needed the static_cast is used, which discards the result and can potentially be optimized out. Without that check, you could pass any value which would make the information in the assertion meaningless.
it is the 'c++ way' of writing
(void)param;
it makes 'use' of the variable and thus disables the compiler warning for unused variable
static_cast<void>(param); will evaluate the param and discard the result.
If you don't add the cast to void:
you may get warnings saying you are ignoring the result of
expression.
Even if you pass some illegal code (for example a statement instead of expression) as argument, compiler will accept it happily.
From cppreference
4) If new_type is the type void (possibly cv-qualified), static_cast
discards the value of expression after evaluating it.

Stop code in variable?

Is it possible to stop or abort a fortran program with an error code/message in a variable? It seems it's not possible with the intrinsic STOP:
integer :: status = 1
character(len=3) :: err_msg = "err"
stop status
stop err_msg
Both stop calls throw syntax errors on compilation. Am I missing something, or do I have to call stop 1 directly, for example? Or write my own wrapper?
Up to Fortran 2003 the stop code can be either a scalar-char-constant or a sequence of up to 5 digits. A scalar-char-constant means what others might call a string, eg your "err" but not your err_msg.
In Fortran 2008 the stop code can be an expression which returns either a scalar-default-char-constant-expr or a scalar-int-constant-expr. If you had a Fortran 2008 compliant compiler then you could use a parameter (eg something declared as character(len=3), parameter :: err_msg = "err") as a stop code
Of course, the state of implementation of features introduced in the 2003 and 2008 standards varies from compiler to compiler and version to version. It looks as if your compiler version doesn't go beyond the Fortran 2003 standard.
And what your operating system does with the stop code is another matter.
Beyond requiring F2008 - no - not in a variable. In F2008 the stop code must be an integer or character constant expression. Variables are not constants - an expression that relies on the value of a variable is not a constant expression.
If you added the parameter attribute to the declarations of status and err_msg then they would be [named] constants, and could be used as a primary in the constant expression for a stop or error stop statement.
The current standards make no allowances for variables in stop codes. However, they have become more and more flexible as High Performance Mark already stated.
In the upcoming Fortran 2015 standard (working document from 2016/05/01, section 8.4) the stop code can be either a scalar-default-char-expr or a scalar-int-expr. So your code will work with a compliant compiler.
This feature of Fortran 2015 was added in version 7 of GCC.