Hi all,
I wrote a fortran module called arithmetic_mod in order to handle different type of input values such as integer, real and complex as follows:

``````module arithmetic_mod
implicit none
private
contains
integer, intent(in) :: n_1, n_2
integer :: sum
sum = n_1 + n_2

real, intent(in) :: n_1, n_2
real :: sum
sum = n_1 + n_2

complex, intent(in) :: n_1, n_2
complex :: sum
sum = n_1 + n_2
end module arithmetic_mod
``````

I tried to test the module in a separate file as follows:

``````program test
use arithmetic_mod
implicit none
integer :: i_num_1 = 2, i_num_2 = 3
real :: r_num_1 = 25.0, r_num_2 = 35.0
complex :: com_num_1 = (7, 8), com_num_2 = (5, -7)

print "(a8,i1)", "2 + 3 = ", adder(i_num_1, i_num_2)
print "(a14,f4.1)", "25.0 + 35.0 = ", adder(r_num_1, r_num_2)
end program test
``````

and i compiled these files using commands below:

``````gfortran -c arithmetic_mod.f90 test_arithmetic.f90
gfortan arithmetic_mod.o test_arithmetic.f90
``````

But when i ran ./a.out , i got output below:
2 + 3 = 5
25.0 + 35.0 = 60.0
(NaN, NaN)

The questions is why complex adder returns NaN instead of correct output(12.000000, 1.000000)?

The problems are in your 3 functions. The results are not set up properly. You have two options to solve the problem, for the integer adder:

1. you must define the result with the function name āint_addā:

sum = n_1 + n_2

1. or you can add result(sum), after function int_add(n_1, n_2). So that you have:

1 Like

You may have noted Fortran as a programming language has a standard and is supported by more than processor with different levels of support and guidance for practitioners. If you were to try Intel Fortran compiler in a āpedanticā mode on the code you show in the original post, you could get a response as follows:

C:\temp>ifort /c /warn:errors arithmetic_mod.f90
IntelĀ® Visual Fortran IntelĀ® 64 Compiler for applications running on IntelĀ® 64, Version 19.1.1.216 Build 20200306

arithmetic_mod.f90(10): error #6178: The return value of this FUNCTION has not been defined. [INT_ADD]
---------------------^
arithmetic_mod.f90(16): error #6178: The return value of this FUNCTION has not been defined. [REAL_ADD]
------------------^
arithmetic_mod.f90(22): error #6178: The return value of this FUNCTION has not been defined. [COMPLEX_ADD]
---------------------^
compilation aborted for arithmetic_mod.f90 (code 1)

C:\temp>

Unfortunately with gfortran even with its āpedanticā settings, the compiler raises no alerts to bring your attention to the issue. Perhaps you can get involved with the GCC gfortran community and contribute toward compiler enhancements that can help you and other future Fortranners like you who may be using gfortran whilst learning the language:

C:\temp>gfortran -c -std=f2018 -Wpedantic -pedantic-errors arithmetic_mod.f90

C:\temp>

1 Like

@kargl wrote:

The option `-pedantic` should be avoided (unless you actually know about some of its idiocracies).

I refer to this site (https://gcc.gnu.org/onlinedocs/gfortran/Error-and-Warning-Options.html#Error-and-Warning-Options) when I point gfortran compiler options to readers. The description of ā-pedanticā option therein doesnāt give me the same sense of avoidance as above comment.

Anyways I only thought of āpedanticā because the Fortran standard places the responsibility squarely on the programmer to define the function result in a subprogram and it doesnāt require the compiler to diagnose the absence of such definition though compilers can go the extra yard in helping their users if they choose to do so. So a mode where a warning along such lines, possibly upgraded to an error, catches the attention of a programmer comes as a good pedantic aid. Hence my choice of -Wpedantic along with -pedantic-errors.

But when gfortran didnāt issue an alert with āpedanticā and given the statement in the above link which says, āimprovements to GNU Fortran in this area are welcome,ā it appeared to me the GCC gfortran community is open to compiler enhancements on this aspect where OP can make useful contributions also.

3 things pop out right away:

1. You need to define the function result variable before completing execution of a function.
2. Using the name of an intrinsic function (such as SUM) as a variable name is generally confusing and not a good programming form.
3. Fortran already has overloaded the + operator to do what this module is attempting. It does not make sense to write a module like this, unless it is an exercise in learning how generic interfaces work.
1 Like

My habits in the debugging phase are to use those options:

``````\$ gfortran -Wall -Wextra -std=f2008 -pedantic -g my_program.f90
``````
• `-Wextra` will give more warnings
• `-g` adds debugging information into the executable

The option `-fbounds-check` can also be interesting to check array bounds at execution.
See for example:
https://faculty.washington.edu/rjl/uwamath583s11/sphinx/notes/html/gfortran_flags.html

1 Like

@FortranFan, perhaps, you should familiarize yourself with the gfortran manual.

@kargl, please donāt say such things in this forum, because it can be seen as disrespectful (we have a Code of Conduct at this forum: Welcome to Discourse) and it assumes that @FortranFan fan is not familiar with the GFortran manual, which is an incorrect assumption (@FortranFan is very much familiar with the GFortran manual), but even if that was correct, you can say the same thing respectfully, for example you can say something like:

ā@FortranFan, I think this is explained in the GFortran manual, in particular you can try adding the `-Wall` option. ā¦ā

3 Likes

The gfortran `-Wall` is detecting your problem.
One funny thing is that on my system I donāt obtain (NaN, NaN) but (0.0, 0.0):

``````2 + 3 = 5
25.0 + 35.0 = 60.0
(0.00000000,0.00000000)

\$ gfortran --version
GNU Fortran (Ubuntu 9.3.0-10ubuntu2) 9.3.0
``````

I donāt know where the numerical result is taken in the memory if `result(sum)` is not specifiedā¦ But it seems we have different values at that addressā¦

An interesting question is: why does the compiler only prints a warning? Should it not be an error message? A function which returns nothing is quite strange. If it has a declared type it should return somethingā¦ either using the name of the function or the `result()` statement.

2 Likes

Steve, I 100% believe that you didnāt mean it to be disrespectful, and it possibly wasnāt received as such. I donāt think that any of the specific words in that statement were disrespectful. However, the tone could be interpreted as disrespectful or condescending. @certik gave a nice example of how that could have been expressed more gently.

We really donāt know and we canāt assume. Calling another userās comment āflippantā is also not constructive. If you found that another userās comment was uninformed or not thought-through, itās an opportunity to point them (with an URL for example) to the correct part of the documentation. Perhaps even explain why `-Wall` is more appropriate in this context than `-pedantic`. It would help other readers here (including myself) as well.

If you found that another userās comment was provocative or disrespectful in any way, please let the moderators (me, @certik, or @lkedward) know via direct message and weāll deal with it.

3 Likes

Otherās have already pointed out the two ways to go about correcting the error. Whatās really baffling to me is how `int_add` and `real_add` managed to actually produce the right result since you made the same error there. Anybody else notice that and have any ideas?

2 Likes

Youāre right, I was surprised as well.

2 Likes

Iām fairly certain Iāve made the same mistake before of thinking Iāve set the return value in a function but in fact I have not.

My guess is that it is by coincidence. For the `integer` and `real` cases, the result of the addition fits into a single 32bit register; the add op has probably used the same register that is used as the function return value. Without further statements in the function, the sum value is left in the return register so the correct result is returned by coincidence of register choice.
(One of the worst kinds of bug: code is wrong, but works by coincidence.)

I agree it is peculiar; I canāt find anything in the standard interpretation document about the behaviour or validity of functions that donāt set their function result. This is probably because, as you point out, there is no use of such a function in Fortran.

3 Likes

Does it mean that a Fortran compiler:

• prints an error message when the code breaks an explicit rule of the standard,
• prints a warning in other problematic cases ?

Good point.

Also, it appears it is `-Wreturn-type` compiler option that leads the compiler to issue the warnings with the code in the original post.

However, unfortunately the description of this option is missing in the link I provided above nor is it indicated this option is included with `-Wall`. Is this an area where GCC-gfortran compiler ādocumentationā can be improved?

Since gfortran is looking for new contributors (see this), perhaps several or many among from the developing community at Fortran-lang can contribute to GCC-gfortran community as well and help improve documentation as needed and help enhance the compiler? After all, gfortran compiler appears to be used heavily by quite a few here.

The main 2 points of my post above were

1. to use compiler options (I steered myself toward `-Wpedantic` because that made sense to me) that help with diagnostics (note @ELNS had used `gfortran -c arithmetic_mod.f90`) and
2. to bring attention to @ELNS and other readers here they can contribute to open-source initiatives such as GCC-gfortran enhancements as well.

@kargl Just out of curiosity, is ā-pedanticā a sort of āhistoricalā thing (as of 2020), as long as gfortran is concerned? I usually use only -Wall -Wextra etc, and was wondering what is the purpose of ā-pedanticā some time ago.

On the other hand, is ā-pedanticā still useful for other GCC languages (say C)?

Note: just found out -Wreturn-type is a GCC option that applies to gfortran as well
https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wreturn-type-Wreturn-typem

GCC āmanualā suggests `pedantic` is a synonym of `Wpedantic` which is used to āIssue all warnings ā¦ā and I didnāt find any mention of any change to handling of twos-complement integers. As much as Iāve referred to GCC/gfortran over the years which is exclusively to try to help other Fortranners online who are using GCC and gfortran in their work, my understanding may be inadequate. Nonetheless, it will be most surprising if such a āwarningā option indeed changes integer semantics.

gfortran users will benefit if someone can confirm this is indeed the case and illustrate the impact with a minimal working example (MWE).

c.f. Wikipedia: " In computing, a minimal working example (abbreviated MWE ) is a collection of [source code] (Source code - Wikipedia) and other data files which allow a bug or problem to be demonstrated and reproduced."

The above comment aināt that for sure. Where is the issue?

``````   integer :: i, j
character(len=*), parameter :: fmtz = "(g0,1x,z0)"
j = 42
i = iabs(j)
print fmtz, "i = ", i
print fmtz, "j = ", j
if ( i /= j ) error stop "-Wpedantic causes an issue"
stop "-Wpedantic makes no difference."
end
``````

C:\Temp>ifort /standard-semantics /warn:all /stand:f18 p.f90 /exe:ifort-p.exe
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.1.1.216 Build 20200306

p.f90(4): warning #8891: Specific names for intrinsic procedures are obsolescent in Fortran 2018. [IABS]
i = iabs(j)
-------^
Microsoft (R) Incremental Linker Version 14.25.28612.0

-out:ifort-p.exe
-subsystem:console
p.obj

C:\Temp>ifort-p.exe
i = 2A
j = 2A
-Wpedantic makes no difference.

C:\Temp>gfortran -Wpedantic p.f90 -o gcc-p.exe

C:\Temp>gcc-p.exe
i = 2A
j = 2A
STOP -Wpedantic makes no difference.

C:\Temp>