Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29273 Discussions

compile time parameter constants and STOP statements

Izaak_Beekman
New Contributor II
1,791 Views
I get an error if I try to pass an integer component, which is greater than 0, of a compile-time constant derived type.

e.g.
[cpp]  INTEGER, PARAMETER         :: name_len = 30
  TYPE error_pair
     CHARACTER(len=name_len) :: name
     INTEGER                 :: code
  END TYPE error_pair

  TYPE(error_pair), PARAMETER :: error_code_not_found  = error_pair('error_code_not_found          ', 5000 )[/cpp]

[plain]STOP error_code_not_found%code[/plain]
Is this really in violation of the standard? I can use a compile time integer constant (parameter) as an argument to stop successfully. Why can't I do this?


(Here's the error msg.)
[plain]ifort -c modErrors.f90 -warn all -check all -traceback -g -sox
modErrors.f90(148): error #5082: Syntax error, found '%' when expecting one of:  ;
       STOP error_code_not_found%code
--------------------------------^
modErrors.f90(148): error #6252: This format specifier is invalid.   [5000]
       STOP error_code_not_found%code
------------^
compilation aborted for modErrors.f90 (code 1)
[/plain]


0 Kudos
1 Solution
Steven_L_Intel1
Employee
1,791 Views
Ah, it seems we're a bit ahead of ourselves. Fortran 2008 allows use of a scalar-char-initialization-expression or a scalar-int-initialization-expression, which your example would conform to. We're only part-way there at present. Your code is not F2003-standard, though. I will request that the compiler give a standards warning for use of a named constant integer constant here. A named character constant is standard F2003, but a character component of a derived type is not.

Tim, STOP is not deprecated. In fact, it was extended significantly in F2008.

View solution in original post

0 Kudos
9 Replies
TimP
Honored Contributor III
1,791 Views
It's not surprising to see compilers supporting STOP only in ways commonly found in legacy applications. Recent textbooks recommend alternates over STOP usage.
0 Kudos
Steven_L_Intel1
Employee
1,791 Views
Here's how the standard describes it:

21 R849 stop-stmt is STOP [ stop-code ]
22 R850 stop-code is scalar-char-constant
23 or digit [ digit [ digit [ digit [ digit ] ] ] ]
24 C834 (R850) scalar-char-constant shall be of type default character.

Note that the numeric code is not a "constant" but rather a series of digits. I am, to be honest, astonished that we allow a named constant to be used there and don't give a standards warning for it. In any event, we did not extend that to a component of a derived type parameter.
0 Kudos
Steven_L_Intel1
Employee
1,792 Views
Ah, it seems we're a bit ahead of ourselves. Fortran 2008 allows use of a scalar-char-initialization-expression or a scalar-int-initialization-expression, which your example would conform to. We're only part-way there at present. Your code is not F2003-standard, though. I will request that the compiler give a standards warning for use of a named constant integer constant here. A named character constant is standard F2003, but a character component of a derived type is not.

Tim, STOP is not deprecated. In fact, it was extended significantly in F2008.
0 Kudos
Izaak_Beekman
New Contributor II
1,791 Views
Ah, it seems we're a bit ahead of ourselves. Fortran 2008 allows use of a scalar-char-initialization-expression or a scalar-int-initialization-expression, which your example would conform to. We're only part-way there at present. Your code is not F2003-standard, though. I will request that the compiler give a standards warning for use of a named constant integer constant here. A named character constant is standard F2003, but a character component of a derived type is not.

Tim, STOP is not deprecated. In fact, it was extended significantly in F2008.

So let me just make sure I understand:

F2003 named character or integer compile-time constants are not allowed in STOP statements.
F2008 Allows scalar named character or integer compile-time constants.

As of F2008 a component of a compile-time constant derived type is never allowed.

I agree that best practice is to pass errors up to the calling routine, but ultimately STOP statements are usefull when glueing different codes together with shell scripts. On many *nix systems it seems that if execute a STOP statement with a numeric error code it will set the environment variable $? to the code specified. This in turn lets you pass errors all the way up to the script which called your fortran code.

Also, more flexibility in specifying the numeric error code with the STOP statement would be extraordinarily helpfull for abstracting error handling routines. With the ability to write to stderror (provided by the intrinsic module ISO_Fortran_env) it seems that stgrings passed to STOP should be somewhat depreciated (since now you can just write an error msg to stderr before the STOP statement). On the otherhand greater flexibility of passing an integer to the STOP which in turn will pass the exit error code up to the calling script would be very nice.

Looks like I missed the boat on that opportunity, it will probably be at least another decade before I have the chance to suggest added functionality along these lines be implemented in the standards, and then possibly another decade for compiler vendors to implement it.
0 Kudos
Steven_L_Intel1
Employee
1,791 Views

No, you have it backwards in places.

In F2003, a named character constant is allowed in STOP, but a named integer constant is not.
In F2008, any scalar, integer or character (default kind) initialization expression is allowed, which includes a component of a derived type or even an expression (as long as it is an initialization expression)

I will comment that the standard simply says that the stop code be "made available" - that doesn't require that it be an exit status, though we do support that. A conforming implementation could just print the text and then exit with a zero (or whatever) status.

I'll suggest that what you would really like is structured exception handling. Don't hold your breath for this one.

My personal preference, given the lack of exception handling, is to write procedures as functions returning error codes, and to check error codes after calls, doing whatever is necessary to recover or abort from errors. I dislike the use of STOP except as a "I am completely hosed and give up" type of condition.
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,791 Views

What was the reasoning for disallowing runtime integer variables to be used in the STOP statement?
(Fiddler on the roof - my guess '"tradition")

Jim

0 Kudos
Steven_L_Intel1
Employee
1,791 Views
I have no idea.
0 Kudos
Izaak_Beekman
New Contributor II
1,791 Views
I will comment that the standard simply says that the stop code be "made available" - that doesn't require that it be an exit status, though we do support that. A conforming implementation could just print the text and then exit with a zero (or whatever) status.

I'll suggest that what you would really like is structured exception handling. Don't hold your breath for this one.

My personal preference, given the lack of exception handling, is to write procedures as functions returning error codes, and to check error codes after calls, doing whatever is necessary to recover or abort from errors. I dislike the use of STOP except as a "I am completely hosed and give up" type of condition.

Yes, I would kill a man for better, more abstract, and language-integrated exception handling. As you said, your (Intel's) implementation does provide the integer passed to STOP as the exit status, so you can do things like:

[shell]./a.out || exit -200 # Something bad happened![/shell]
or

[shell]./a.out
case $? in
    0)
	# Continue with our script
	;;
    1)
	# Error type 1, maybe an unrecoverable error, or just an indication that we should do something else now
	;;
    20)
	# Error type 20, different scenario, do something different.
	;;
    *)
	
esac[/shell]
This is nice, and it's a pity that this behaviour (passing the STOP integer constant as the exit code) is not part of the standard and that it's such a pain to handle exceptions/errors in Fortran. At least the F2008 langauge features you mentioned give the developer a few more options in developing abstract, robust, and user friendly exception handling routines.

-Z

(Thnaks again for all the input/answers everyone!)
0 Kudos
Steven_L_Intel1
Employee
1,791 Views
The Fortran standard very carefully abstains from any attempt to define the environment in which a Fortran application runs, though in more recent versions of the standard it has dipped its toe in, so to speak (GET_ENVIRONMENT_VARIABLE, GET_COMMAND_ARGUMENT, etc.) The notion of an "exit status" is not specified, though I think you'll find that most implementations do indeed pass a numeric stop code as an exit status.
0 Kudos
Reply