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

Compiler warning with character*(*) function

michael_green
Beginner
1,407 Views

The following works OK ...

character*(*) function upper(string)

!Returns the upper case version of the input STRING.

implicit none

character*(*) string
character*1024 temp
integer*4 i,l

l = len(string)
temp = string

do i = 1,l
if(temp(i:i).ge.'a'.and.temp(i:i).le.'z')then
temp(i:i) = char(ichar(temp(i:i))-32)
end if
end do

upper = temp(1:l)

return
end

But the compiler warns me :

Warning: A CHARACTER function name must not be declared with an asterisk type-param-value (i.e., (LEN=*)) if the function is part of an interface-body. No interface block will be generated. [UPPER]

Can I just ignore this or is there a better way to write the function?

With many thanks

Mike

0 Kudos
9 Replies
TinTin_9
Beginner
1,407 Views
Strange, I just copy-pasted your function as it is and compiled it and it gave me no warning, i even used it on a test case successfully.

Can you please post your calling program here ?

Thanks..

0 Kudos
TimP
Honored Contributor III
1,407 Views
I take it that /gen-interfaces was set. character *(*) is one of the few things which was new in f77 which I believe is disrecommended since f90. In the present context, I believe it was not strictly legal in f77, which would take away f77 compatibility as an argument for using this syntax.
character(len=len(string)) function(string)
appears to be a legitimate equivalent (in f90), by my reading of MR&C. If this doesn't work, with or without /gen-interfaces, I think it would be worth a submission on premier.intel.com for further study.
Of course, if you're trying to find something which doesn't involve abuse of Fortran syntax, you'll also fix integer*4.
Something like
character(len=len(string)) temp
might be better, given that you are using an f90 compiler, unless you can guarantee that len=1024 will not be exceeded, and that 1024 is not an excessive extension of the string length.
This code appears to be trying to fit within f77, "except for a few exceptions," to its detriment.
0 Kudos
Steven_L_Intel1
Employee
1,407 Views
Tim has it mostly right. CHARACTER(*) is fine in current Fortran for dummy arguments, but is deprecated for function declarations and it's not supported for use in interface blocks. Because new projects default to /gen-interface, the compiler wants to generate an interface for this function but can't, hence the warning.

Tim also has the right approach for a modern replacement, but using this requires an explicit interface to be visible to the caller (and a generated interface won't do.)

You could ignore the warning, or even turn off generated interface creation and checking if this is a concern to you.
0 Kudos
michael_green
Beginner
1,407 Views

/gen-interface was not set, but it made no difference either way anyway.

The following:

character(len=len(string)) function upper(string)

does not compile. I get "The data types of the argument(s) are invalid. (LEN)"

Maybe I'll just take Steve's advice and ignore the warnings.

Many thanks

Mike

0 Kudos
Steven_L_Intel1
Employee
1,407 Views
Generated interfaces had to be enabled or otherwise you would not have received that initial message. It is on by default in a newly created project. Look under Project > Properties > Fortran > Diagnostics
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,407 Views
michaelgreen:

The following:

character(len=len(string)) function upper(string)

does not compile. I get "The data types of the argument(s) are invalid. (LEN)"



Didn't test myself, but most likely it's just an issue of declaration order. The following certainly works:
function upper(string)
character(*), intent(in):: string
character(len=len(string)):: upper

0 Kudos
michael_green
Beginner
1,407 Views

Thanks, Jugoslav,

That certainly compiles and nearly gives the right answer, but there is a small problem that I am unable to solve. If I have:

character*20username,upper

character*128line

username = 'MichaelG'

line = 'michaelg,manager,casual,user'

i = index(line,',')

if(upper(line(1:i-1))==upper(username))found = .true.

found remains false because upper(username) = 'MICHAELG' but upper(line(1:i-1)) = 'MICHAELG#%&!!'Actually, I get Chinese characters after my name, but the point is the same. Sorry to be a pain.

Thanks for your help,

Mike

0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,407 Views
michaelgreen:

character*20 upper

upper(line(1:i-1)) = 'MICHAELG#%&!!'Actually, I get Chinese characters after my name, but the point is the same.


Exactly: you get "MICHAELG" plus some random garbage off the stack, to make the 20 characters -- because you've just falsely declared upper to return a 20-character string. You have to have an explicit interface (best, function Upper in a MODULE) to have it work as desired.
0 Kudos
llynisa
Beginner
1,407 Views

I have never had any problems with the following conversion routine which seems to avoid some of the problems above.

function Upc(String)
! Returns String in upper case. String itself is not converted.
use user32, only : CharUpper
implicit none
character*(*), intent(in) :: String ! Input string.
character(len(String)) :: Upc ! Function type.
integer*4 :: i ! Working variable.
Upc = String ! Set Upc to preserve String.
i = CharUpper(Upc) ! Convert String using WinAPI function.
return
end function Upc

HTH

Bear of Little Brain

0 Kudos
Reply