Error in implicit statement: Parameter ‘a’ has not been declared - fortran

I am working on a old Fortran code. Until this morning I was able to compile it. But today,I did not change anything, it says
impli.for:1:33:
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
1
Error: Parameter ‘a’ at (1) has not been declared or is a variable, which does not reduce to a constant expression
Do you know how can I fix it? It's a old code and I don't want to change so many things.
I compile using gfortran.

Related

How can I specify in fortran compiler that declared variables shoud not be potentially treated as implicit function declaration

I was pretty surprised that :
subroutine test (es, f)
!
implicit none
!
double precision es
double precision f
f=es(1,2)
!
return
end
compiled without any error or warning : es is not declared with dimension.
I understand that es is then considered as a function.
But when linking there is no error considering the missing symbol es !
Looking at the assembler es(1,2) corresponds to call rdx, hence no link error.
To avoid this problem I can declare es as double precision, intent(inout) then I get :
Error: PROCEDURE attribute conflicts with INTENT attribute in 'es' at
Which is what I was expecting the first time.
Question
Is there a compiler option (ifort or gfortran) to force the declared variables to be treated as intent(inout)and not as procedure call ?
Thank you in advance.
Ps: I have a legacy code and I do not want to add intent(inout) everywhere to detect this kind of misinterpretation.
"But when linking there is no error considering the missing symbol es !"
There is not supposed to be one. es is the name of the dummy argument, not the name of the actual procedure that you would pass there. What would actually happen in most implementations that the code would try to call the pointer to the variable as a function address and that would lead to some kind of error. Either executing non-executable code, or invalid instruction or executing a virus code carefully put to the right location of the stack or heap by an intruder.
"Is there a compiler option (ifort or gfortran) to force the declared variables to be treated as intent(inout)and not as procedure call ?"
No, and even if it were it would break the code semantics and that is a BAD THING(TM). Anyone using the code somewhere else or without the option would be screwed. Especially the point that it creates a possible dangerous code vulnerability is a clear reason to not allow such a thing.
It is better to say that explicitly,even though I believe you are aware of this and just want a diagnostic tool to warn you:
The correct declaration of an array involves its dimension, like
double precision es(1,*)
Also be aware that the compilers are able to check for similar errors when calling the procedure. Gfortran will find out when the calling code is in the same file, Intel sometimes even if not (when -warn interfaces is enabled). Enabling link time optimizations may also help to find it. And of course, modern Fortran should use modules.
Consider:
subroutine test (es, f)
!
implicit none
!
double precision es
double precision f
f=es(1,2)
!
return
end
double precision a(2,1), b
call test(a, b)
end
Because the call is in the same file, gfortran will automatically, without any additional option, identify the problem:
declaration.f90:14:13:
call test(a, b)
1
Warning: Rank mismatch in argument ‘es’ at (1) (scalar and rank-2) [-Wargument-mismatch]
Intel will require the warning flag
ifort -warn interfaces declaration.f90
declaration.f90(14): error #6637: When a dummy argument is a function, the corresponding actual argument must also be a function. [A]
call test(a, b)
-------------^
compilation aborted for declaration.f90 (code 1)

Length-parameterized passed object to type-bound procedure has gfortran complain

I'm learning Fortran and I'd like to encapsulate an array and a subroutine in a type. The problem appears to be in the type definition of the self-object.
This is the minimal test case I came up with:
module testing
implicit none
type test(para)
integer, len :: para
real, dimension(para) :: weights
contains
procedure :: testing => testing_test
end type
contains
subroutine testing_test(self)
class(test(*)) :: self
end subroutine
end module
Compiling this with gfortran raises this error:
module_test.f08:9:23:
procedure :: testing => testing_test
1
Error: Argument ‘self’ of ‘testing_test’ with PASS(self) at (1) must be of the derived-type ‘test’
It works when the array-length is fixed (so type%para doesn't exist)
Is what I'm trying to do (type with array of variable size and bound procedure) plain impossible or am I missing something regarding dummy argument definition?
Thanks to #Rodrigo for the idea, I finally found this bug (and patch):
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82943
To fix the issue, download the source, apply the mentioned patch and compile your own gfortran. (Or wait until it's in the repositories)
This is not really an answer but may provide a solution for some. gfortran-10 still has the same problem. However flang-7 compiles this example and it is available for Ubuntu since 19.10, and maybe other OS:es.
A previous answer points to a bug report and patch for gfortran. It is worth saying, though, that this is standard Fortran (2003) code.
What we have here is a type-bound procedure with passed-object dummy argument. The main restrictions of such an argument are that it is a:
scalar,
nonallocatable,
nonpointer object,
with all length-type parameters assumed.
Further, as the type is extensible the passed-object dummy argument must be polymorphic.
For the example of the question, all of the conditions are met.

fortran 77 conflicting types in external

I'm working with a F77 code, and I am encountering a problem in the compilation. I think I've narrowed down the problem but don't know a straight forward way of fixing it.
The code is extremely long so I'll try to be as clear as possible with the little snippets I use.
The error is the following:
/tmp/fort77-4812-1.c:2728:12: error: conflicting types for ‘func_’
doublereal func_(doublereal *e)
/tmp/fort77-4812-1.c:272:43:
note: previous declaration of ‘func1_’ was here
extern /* Subroutine */ int func1_(), func2_();
^
where func(n) is some function. This happens with both func1 and func2 and they both have the same format, they differ in arithmetic.
The code starts like this:
Implicit double precision(a-h,o-z)
...
//initialization of some Arrays & parameters
...
external func1,func2
...
...
...
function func1(n)
implicit double precision(a-h,o-z)
...
...
end
I think the external is trying to keep the function as int but it is defined as a realdouble because of the implicit double.
Any thoughts?
This looks like an error caused by your choice of compiler, which I am assuming is f2c, which is a language translator. The problem is the translation is not handling the external attribute declaration properly and is producing a C language variable declaration which is not respecting your implicit typing rules (which appears to be a bug I cannot reproduce with f2c version 20060506).
I recommend using a proper Fortran compiler instead of f2c.

VS 2013 error C2664 when trying to compile a .c file as .cpp

I am on my way of programming my first external for Max 6, but the entitled error is holding me back. I have crawled for a week the web to find a solution to the entitled problem, but no luck. There are many topics related to
error C2664: cannot convert parameter 1 from 'X' to 'Y'
but none of the proposed solutions was suitable for my case, since it seems to be a Max object case-specific.
More to the point, I have a main .c file for my external that makes use of various other .cpp files and libraries. For that reason I want to compile it as a .cpp file. As far as I know, there shouldn't be a problem with that. However, when I am trying to compile it in Visual Studio I get the following error:
error C2664: 't_object *object_alloc(t_object *,const char *,...)' : cannot convert argument 1 from 'void *' to 't_object *' "
Has anyone faced and managed to solve any similar issue? Is it the case that I am missing something more profound?
Thank you in advance!
C++, unlike C, does not permit implicit conversion of a void pointer to a non-void pointer. It seems that you are trying to pass a void pointer as the first argument to that function, but since it can't be converted to the parameter type, an error occurs.
You can solve this by casting the void pointer directly to the target pointer type.
object_alloc(static_cast<t_object*>(p), ...)
(FYI, the conversion in the reverse direction---non-void pointer to void pointer---is a standard conversion and can occur implicitly. static_cast is allowed to perform the reverse of standard conversion sequences.)
In C there is an implicit conversion from void* to any data pointer type.
Together with C's implicit function declarations this means that in C it's not a good idea to cast the result of e.g. malloc, because with a missing header (no malloc declaration) that will implicitly declare malloc with result type int, and at least the local code will compile with no visible error... :(
In C++ there is no implicit conversion from void*.
So in C++ one not only should but most often must cast the result of e.g. malloc.
Happily C++ does not have implicit function declarations. :)
A good solution for your specific problem may be to compile the C file as C (duh).
However, be aware that the top level control of a combined C and C++ program, should better be C++. I.e. compile main as C++. That's because C++ has some extra runtime library requirements such as dynamic initialization of things.
Instead of an implementation file that can compile as either C or C++, consider just a header (with only pure declarations) that can be used with both languages. This is the common way to do things. You can use a conditional extern "C" to make the declarations work fine also in C++.

Cannot assign to INTENT (IN) variable x at (1) - How can this be solved?

While compiling a Fortran program with gfortran (mpif90), I encounter the following error:
Error: Cannot assign to INTENT (IN) variable 'x' at (1)
make[2]: [module.o] Error 1 (ignored)
When I compile this program with PGI, I do not receive this error.
I've got two questions regarding this.
What is the meaning of this error?
How can I make gfortran and mpif90 compile this module file similarly to PGI? Is there a flag that I can pass to tell the gfortran compiler not to worry about this?
Any suggestions would be appreciated.
If you'd shown us the code this might be more than a guess but here goes ...
You have a procedure, either a function or a subroutine, something like
integer function my_func(x)
real, intent(in) :: x
...
x = a_value
my_func = 2
end function my_func
The statement real, intent(in) :: x tells the compiler that the function will not attempt to alter the argument x. And then, bang, in x = a_value, the function goes right ahead and attempts to alter the argument.
This behaviour by the compiler is a tremendous aid to safe programming and if the PGI compiler really doesn't raise an error on encountering such code then (a) it is in error, the standard requires that it should and (b) you should not be using an unsafe compiler.
Other compilers are quite right to raise this error and even if I knew a way to tell a compiler not to I wouldn't share it with you. It would be like teaching you how to remove the safety guard from a bacon-slicing machine.
Now, show us your code and one of us can give you a proper diagnosis.