String comparison fails

String comparison fails

I am performing a simple string comparison that returns false when it should return true. The line of code is:
IF (A(9) .EQ. ' ') THEN
When I put a break point on this line and check the value of A(9) it is ' ' just as it should be but the result of the statement is false and the ELSE part of the IF statement then executes. A is declared by:
CHARACTER*52 A(25)
and is part of a common block. I have also found that the intrinsic string functions aren't working here either. Do I have something wrong here?

23 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Without seeing the complete program, I can only guess, but my guess is that A(9) contains some characters other than blank - perhaps a NUL. If it displays as '' and not 52 blanks, then that's probably what's happening. Is the variable properly initialized?

Steve

Steve - Intel Developer Support

When I check the value of A(9) during debug it shows a string of 25 blanks. A(9) is declared as shown in the first message.

I had asked if the variable was properly initialized. How does it get its value set?

Your inquiry is not the sort that can be answered based on an excerpt of the code. My guess is that the value is not what you think it is. Your comment about the intrinsic functions not working also suggests that there's an error in your code that you haven't found yet.

If you want us to look at it, send a ZIP file of a complete (but short, if possible) program that demonstrates the problem to vf-support@compaq.com Before doing so, I suggest checking more carefully to make sure that the values assigned are what you want them to be. Don't assume anything...

Steve

Steve - Intel Developer Support

When I check the value of A(9) during debug it shows a string of 25 blanks. A(9) is declared as shown in the first message.

Steve, thanks for your help. A(9) is assigned the value in a database. In this case the value in the databse is a string of 12 characters. The assignment occurs in a C++ module. I inserted a print statement and wrote out the value of A(9) to a text file and it was 52 blank spaces. I could send you some code but you wouldn't be able to run it. This is part of a very large program plus there's the database so I don't think you're going to be able to help me but I do appreciate your trying.

Was A(9) initialized before passing it to the C++ module? If not, it should be. This can cause intrinsic functions not to work as desired. For example,

print *, trim( A(9) )

would not "trim"

C strings are null terminated. Upon return from the C++ module check for imbedded nulls in A(9). This would cause the equality test to fail.

I'm willing to bet that your problems are rooted in these two areas - initialization and nulls. But that basically repeats with what Steve posted earlier. :)

hth,
John

Steve, thanks for your help. A(9) is assigned the value in a database. In this case the value in the databse is a string of 12 characters. The assignment occurs in a C++ module. I inserted a print statement and wrote out the value of A(9) to a text file and it was 52 blank spaces. I could send you some code but you wouldn't be able to run it. This is part of a very large program plus there's the database so I don't think you're going to be able to help me but I do appreciate your trying.

Bingo! That worked! I assigned A(9) to a string of spaces and it ran just fine. Thanks John! Now I wonder how many more of my problems are caused by the OTHER variables that are not initialized going into that C module........ :-)

From Bear of Little Brain

I too have had similar problems, and consequently have adopted safety plays which include never using LEN_TRIM for the length of a string, because that only neglects spaces. I use INTEGER FUNCTION LENGTH(string), for which I do not claim originality, and includes as its vital parts:
L = LEN(string)
DO I = L, 1, -1
IC = ICHAR(STRING(I:I)
IF (IC >= 33 .AND. IC <= 126) GOTO 10
END DO
I = 0
10 LENGTH = I

This consequently finds the first non-printing character working back from the end of the string.

A good thing in this context is to be able to look at output using some facility which will distinguish blanks from ASCII-nulls. This seems to require sending output to a file and carefully selecting an editor which will show these characters in a sensible way. One editor I use seems to skip several lines of good output on finding a null character, which is useless, but I find that PFE shows these null characters well.

I guess it would be good to be able to turn on some special treament for identifying nulls sent to the console or Quickwin type window. anyone know if this can be done?

You can examine the variable in the debugger - I think it's possible to view the individual bytes. The Developer Studio editor has "Open as Binary", which works well for looking at files.

Steve

Steve - Intel Developer Support

It is possible to display individual bytes via the memory window. Pop it up via menu "View", "Debug Windows" and "Memory" while running in debug mode.
Stop the debugger at a position where the value to be shown is active and enter the name of the variable in the address part at the top of the memory window. With the mouse in the memory window you can pop-up a menu (right click the mouse) and select byte format to see the contents as hexadecimal bytes.
The only problem I have is that the requested address starts somewhere in the displayed part of the memory window, but I don't know how to detect the exact start position of the requested value.

Both these last two suggestions would be possible once someone knows there's a problem. The initial step of noticing that there is a problem to be solved is somewhat different. Here, displaying nulls in a way which isn't noticable among ordinary text is not helpful, whereas seeing blocks of graphics characters such as open or filled character blocks tends to stand out. Seeing such things via an editor has certainly helped me in the past. Given that console-type output is more immediately visible than having to edit output files, it is a pity that there seems to be no simple way of effecting this change in the way nulls are displayed in console output.

David Jones

Console output is handled by Windows - CVF has no control over it.

Steve

Steve - Intel Developer Support

When examining strings, to overcome the problem of non-printing characters all appearing as blanks(in the debugger), I always examine them as hex (or octal).
In the Watch debugging window e.g. A,x will expand to show A(9) as 20hex for blank or 0hex for null.

How you can examine a string (I assume a CHARACTER type) as a hexadecimal value in the Watch window? I only succeeded in examining integers and reals as hexadecimal.
This is why I used the method mentioned earlier in this thread.

Guus.

Like Guus, I can only see a string as hexidecimal values in the memory window.

On a more general note related to this thread, does anyone have a case of a problem with nulls in strings, or string instrinsics not working, that can't be fixed by

  • ensuring that the string variable is properly initialized
  • removing the C style null terminator after calling an external C style routine
  • (the most crucial of these steps being the initialization) e.g.,

      
    ! ... pseudo code  
    mystring = " "  
    call foo(mystring, ...)  ! foo is some external C style routine  
    ipos = INDEX (mystring, char(0))   
    mystring(ipos:ipos) = " "   
    

    After reading John's last post I thought maybe it would be informative to update everyone on my original problem. I earlier posted that setting the A(i) array to a single space character solved my problem. However, after more testing I found that it did not. The problem was that the values of the A(i) array are assigned the values of a record in a database and when the values in the database had only non-zero length strings everything worked fine but when a value in the record was a zero length string the problems started. Once I made sure that the A(i) array was populated with non zero length strings AFTER assignment of the values in the database my problem went away for good.

    Just to follow up... If the database had a zero length string, what did the C++ data access layer return? A string whose only character is the null terminator (a sero length string)? If so, then two guidelines above (initialize and replace terminating nulls with a space) prevent the difficulty, no? :-)

    -John

    Hi John/nijhuis,
    In reply to ...
    "How you can examine a string (I assume a CHARACTER type) as a hexadecimal value in the Watch window? I only succeeded in examining integers and reals as hexadecimal. This is why I used the method mentioned earlier in this thread."

    This used to be a big problem debugging and you did need to use the memory window, but now you can use the Watch window.
    As of version 6.5(?) characters strings/arrays can be examined in hex/oct
    see the release notes section 1.12 as below ... (note: 'x' for hex)

    o In previous versions of the product, format specifiers
    had no effect on character variables in watch windows.
    For example, trying to see a character variable 'ch'
    in octal by typing "ch,o" in a watch window, had no
    effect. Support has been added in this release for using
    'o', and 'd'/'i' format specifiers to watch character
    variables.

    Thanks for the pointer to the release notes. It seems that support for 'x' format specifiers in the watch window for character variables was added in 6.5A, although the 6.5A release notes don't mention it. 6.5 handles 'o', 'i', 'd' for character variables as the release notes mention.

    I was looking at a 6.5 installation for my prior post. Sorry for the confusion.

    Thanks,
    John

    I do have version 6.5A, but I was not aware of the possibility to use format specifiers. So, I have learned a useful feature. Thank you.

    Guus.

    Leave a Comment

    Please sign in to add a comment. Not a member? Join today