Silverfrost Forums

Welcome to our forums

write longer string into shorter string

31 Jan 2011 7:56 #7653

Maybe somebody can give details on the following one: there's code that writes a longer string into a shorter one using a '(aNUM)' formatting that looks fine at a first glance, but checkmate (or bounds_check) complain about it, most likely with good reason. Short test program:

program test
   implicit none
   character(len=20) :: short
   character(len=50) :: long

   long = '1234567890'
   write(short, '(a20)') long
end program test

Is there a real problem in the code? The intel compiler does not complain about this during compilation or runtime with maximal checkings enabled.

Thanks for any insight.

31 Jan 2011 9:33 #7654
program test 
   implicit none 
   character(len=20) :: short 
   character(len=50) :: long 

   long(1:10) = '1234567890' 
   write(short(1:10), '(a)') long(1:10)

!  or

   short(1:10)=long(1:10)

end program test
31 Jan 2011 10:37 #7655
write(short(1:10), '(a)') long(1:10)

This is pretty much the code the original was changed into, which passes the checkmate tests. But what I'd like to know is if the original code really is buggy, or some insight into why the 'a(10)' isn't enough.

1 Feb 2011 8:26 #7665

The very same code works perfectly fine on XP (v6.0 ftn95 compiler) both in release mode as well as checkmate, and fails on Win7/64bit.

Further there is some pretty bad memory corruption due to this in some larger application (well-tested under XP and fails in semi-random manner when the non-cropped string is passed to write, and works fine when something like long(1:10) is used instead).

So this is most likely a bug in the ftn95 library.

2 Feb 2011 12:20 #7673

The original code looks wrong to me. The variable 'long' is 50 characters long. You set the first 10 characters to something and the remaining 40 characters to blank (spaces). That is what the assignment does. It always did this in Fortran 77 and it hasn't changed in Fortran 95.

What happens if you try to write this to a character array 'short' of length 20 using a20 formatting? Are the first 20 chararacters supposed to be written? Or should you get an error because the full 50 won't fit?

2 Feb 2011 7:35 #7674

Sebastian,

   short = long    ! would achieve the same intention

You stated

The very same code works perfectly fine on XP (v6.0 ftn95 compiler) both in release mode as well as checkmate, and fails on Win7/64bit.

Your original sample code looks ok to me, for the line you have quoted : 'write(short, '(a20)') long' I would expect it should be working ok. I'm not sure if you say you have confirmed this is definately the cause of the problem, or could it be associated? Have you proved with this simple sample you provided that it is failing in Win7/64 ?

Win7/64bit has different memory allocation and management to XP so if the error is in a larger program, you should consider that this is an error that is caused somewhere else and appearing at this time.

John

2 Feb 2011 7:51 #7675

short = long ! would achieve the same intention

The original code inserts a string into another one so it is not relevant to me to rewrite the sample. The posted code is a minimal sample to reproduce the bug.

Have you proved with this simple sample you provided that it is failing in Win7/64 ?

Yes, this is a default setup of a x64 machine running win7, and it was verified on other machines of the same architecture.

The original code looks wrong to me. The variable 'long' is 50 characters long. You set the first 10 characters to something and the remaining 40 characters to blank (spaces).

Where is the 'wrong' part? The assignment can be arbitrarily different, the faulting code is not related to that but the error only happens in the write statement.

What happens if you try to write this to a character array 'short' of length 20 using a20 formatting?

You mean using character*20 instead of character(len=20) ? This results in exactly the same bug.

Thanks for the answers!

6 Feb 2011 11:32 #7716

Sebastian,

Could the following work on Win 7 ? write (short, '(a20)') long (1:20) ie, making sure all arrays are the same length.

Making short longer, say a temporary character80 may also remove the problem, eg character temp80 write (temp, '(a20)') long short = temp

I don't yet have Windows 7 to test, but will soon, so this problem is of interest to me.

I would recommend that avoiding the use of write for character arrays in your main program would be the best approach. There may be a way. If converting from numeric to character, I use a character function to localise this use. ( a function containing a write statement was probably not legal in F77 but does work for me.) You may be able to identify where Win 7 is failing when doing these changes ??

John

7 Feb 2011 8:54 #7717

Could the following work on Win 7 ? write (short, '(a20)') long (1:20) ie, making sure all arrays are the same length.

Yes, see my first reply in this thread.

I would recommend that avoiding the use of write for character arrays in your main program would be the best approach. There may be a way.

There is no way to check the whole sources for this. And if the code is legal fortran (F90/F95) then there's no reason to change the code.

You may be able to identify where Win 7 is failing when doing these changes ??

It's not Win7 that is failing, it's the Silverfrost C-library that is crashing on this.

7 Feb 2011 10:21 #7718

I will take a look at this shortly.

16 Feb 2011 12:27 #7764

This code should never run for the reason given by davidb above. Whether release or checkmate etc there will be a runtime failure

17 Feb 2011 7:44 #7772

Paul,

I would have expectd that 'write(short, '(a20)') long ' would only require a 20 character buffer, as the format statement defines the output length, not 'long'

John

17 Feb 2011 7:51 #7773

OK I take the point but internal write is only an back-handed external write where the 'file' is assumed to be large enough to take the data.

Maybe the I/O library could have been written differently or maybe it could be modified but this behavoiur seems natural to me.

17 Feb 2011 8:06 #7775

I tried a variation of the original program and ran using /check and all appears to work ok. ( I'm still using Ver 5.40 on my notebook )

program test 
   implicit none 
   character(len=20) :: short 
   character(len=50) :: long 

   long = '123456789012345678901234567890' 
   write (short, '(a20)') long 
   write (*,*) short
   write (*,*) short(1:2)
   write (*,*) long
end program test

John

17 Feb 2011 9:23 #7778

Hey Guys, Jhonchappel, Sabetain, David, Paul...

Please help me out.... I have written my problem in last post like 'Help me... I have problem in fortran'

And also Send me your email address. to send u that program to correct for me.. as I can run it.. man.

Please Please Help me out... my email address. engrsandeep@hotmail.com

regards,

Sandeep

17 Feb 2011 11:05 #7783

I've again tried to test what is happening by identifying the bytes before and after SHORT. Hopefully this code has not shifted the possible problem, but I do not see any overwrite of memory before or after short*20.

I have compiled this code with Ver 5.40 and Ver 5.50 and found no errors. Still looks ok to me !

John

! tests write to short by identifying bytes before and after short
!
   character short*20, long*50, cc(-1:22)*1
   equivalence ( short, cc(1) )
!
   cc   = 'x'
   long = '123456789012345678901234567890' 
!
   write (*,10) 'Before'
   write (*,11) 'cc    ',cc
   write (*,11) 'short ',short
   write (*,11) 'long  ',long
!
   write (short, '(a20)') long 
!
   write (*,10) 'After'
   write (*,11) 'cc    ',cc
   write (*,11) 'short ',short
   write (*,11) 'long  ',long
10 format (/a)
11 format (a,':',25a)
end

subroutine test 
   implicit none 
   character(len=20) :: short 
   character(len=50) :: long 

   long = '1234567890' 
   write(short, '(a20)') long 
end subroutine test
21 Feb 2011 2:07 #7808

Maybe the I/O library could have been written differently or maybe it could be modified but this behavoiur seems natural to me.

The behaviour is anything but natural, it does neither create a crash nor a checkmate exception when running it under XP, and it creates application fault boxes when run under 64bit windows (up to random crashes in a real world application).

Is the code bad? Then checkmate should warn under XP as well. If it is correct (and at the moment I don't see a reason why it should not be correct, and other compilers seem to agree on this) then something needs to be done about the behaviour under win7/64bit.

21 Feb 2011 3:32 #7809

I have tested the original program in this thread under XP and all the common compiler modes and I always get a runtime failure... 'Attempt to write past the end of internal file'.

Sorry but that's the best I can offer unless I have missed the point.

21 Feb 2011 11:44 #7810

Paul,

You say 'I have tested the original program in this thread under XP' however, I am not getting the results you have indicated. I have FTN95 Ver 5.40.0 on XP (win32) and Ver 5.50.0 on XP-x64 Both the first code example in this post and my last example compile link and run with no identified problems. I use first code as file ch_20.f95 then: ftn95 ch_20 /debug /link and also tried '/check /link', '/p6 /opt /link' and just /link then use either 'sdbg ch_20' or 'ch_20'

I can not get an identified or reported error. Is this a regression applied in Ver 6.0 ?

John

22 Feb 2011 1:52 #7811

It works for me with no problems as well. I am using version 6.0 with Windows Vista.

Please login to reply.