What does implicit none (type,external) do?

Gfortran rejects

function twice(i) result(j)
implicit none
integer, intent(in) :: i
integer             :: j
j = 2*i
end function twice

program main
implicit none
print*,twice(3)
end program main

saying

xex.f90:10:12:

   10 | print*,twice(3)
      |            1
Error: Return type mismatch of function 'twice' at (1) (UNKNOWN/INTEGER(4))
xex.f90:10:7:

   10 | print*,twice(3)
      |       1
Error: Function 'twice' at (1) has no IMPLICIT type

It compiles and runs

function twice(i) result(j)
implicit none
integer, intent(in) :: i
integer             :: j
j = 2*i
end function twice

program main
implicit none (type,external)
integer :: twice
print*,twice(3)
end program main

and also the same code with implicit none without (type,external) appended.

I don’t understand what (type,external) does. When will a code compile with implicit none but not with implicit none (type,external)?

Your second version of main doesn’t have an implicit typing error because you declared the return type of twice.

But you should get an error because of external in the implicit statement. You are calling a procedure without an explicit interface and without the EXTERNAL attribute. That’s what implicit none(external) prohibits.

@Beliavsky,

The standard document proxy is the best place to look, arguably “Modern Fortran Explained” is the next best source to review: I presume you’ve both? A primer:

  • implicit none is equivalent to implicit none ( type )
  • external in implicit none (whether with or without type) means any external and dummy procedure arguments in a given scope must be declared with EXTERNAL attribute if their interfaces are IMPLICIT (e.g., real twice ; external twice

Your question here is really a concern because the way you’ve shown your examples is likely different from an actual scenario where you may have encountered an issue. And you’ve omitted some detail. As to the latter, what I mean is your original post suggests you’ve the function implementation and the program (main) in the same source. Under this scenario, your compiler may take on certain actions (e.g., with interfaces) that can be different should the source be separated in which case the situation will clearly be that of an implicit interface. You will likely then need to consult your compiler manual for information. But in many scenarios where coders are working with Fortran, esp. on Windows, the subprogram sources (usually in DLLs) are separate from callers (in EXEs such as Microsoft Excel; or other DLLs). So the errors can be different from what you show with your attempted reproducer in the same source.

Anyways, note in your first example, a processor technically has no way of knowing whether twice is an array variable or a function.

For reference, I’ll answer the subject question. implicit none (type,external) is a Fortran 2018 feature. implicit none(type) is the same as implicit none, disabling all implicit typing. implicit none(external) requires that any procedures referenced either have an explicit interface or be declared EXTERNAL. You can combine the options.

Compilers supporting this may have a command line option to imply implicit none (external) in the same manner as options to disable implicit typing.

And implicit none (type,external) does not currently work in Intel Fortran, I filed a bug report some months back.

And so you did. implicit none(type, external) discussion - Intel Community

And I remember having a chuckle when I read that, for it felt like the "left hand doesn't know what the right hand is doing" kind of a thing! See below re: flagged warning when /warn:externals is in effect, yet no diagnostic with implicit none ( type, external )

C:\Temp>type p.f90
implicit none ( type, external )
call foo()
end

C:\Temp>ifort /c /warn:externals p.f90
Intel® Fortran Intel® 64 Compiler Classic for applications running on Intel® 64, Version 2021.1 Build 20201112_000000
Copyright © 1985-2020 Intel Corporation. All rights reserved.

p.f90(2): warning #8889: Explicit declaration of the EXTERNAL attribute is required. [FOO]
call foo()
--------^

C:\Temp>ifort /c p.f90
Intel® Fortran Intel® 64 Compiler Classic for applications running on Intel® 64, Version 2021.1 Build 20201112_000000
Copyright © 1985-2020 Intel Corporation. All rights reserved.

C:\Temp>

Anyways, the bug with external appears to be when it’s paired with type.

These are all instances that call for a standard validation and regression testing suite to go with all the features in the ISO standard.

Yes that is correct you can have type or external but not both. I had not noticed /warn:externals I will add that to my standard build options.
EDIT. Having checked I see that /warn:externals is already in my build options. It seems the behaviour has changed with the latest ifort as it only used to warn for functions but it now covers functions and subroutines it would seem. A positive step in my book but i would rather f2018 change worked.