- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I discovered some odd behavior with IFX vs IFORT on a program of mine. To try to minimize details to keep this as short, the program display a live screen on the console, and makes use of the Console API in Kernel32 to reposition the cursor. I decided to compile the program with the newer IFX, and the output screen was corrupted. I thought at first it might be some differences between how IFX handles PRINT and FORMAT statements, but that wasn't.
Running both the IFORT and IFX debug versions of the program and looking at the disassembly output, I discovered this. A 32-bit "COORD" structure should be loaded into the EDX register before the call to the "SetConsoleCursorPosition" function. IFORT does this. However, IFX appears to incorrectly use a 16 bit instruction to just load 16-bits of the structure into the 16-bit DX portion of the register. I've copied and pasted the assembly here:
------------------------------------------------------------------------
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
An old (2009) post in this Forum provides the source code of a subroutine that can be used as the test code for this issue. The IFX disassembly actually shows that three arguments are being passed to SetConsoleCursorPosition rather than the expected two: one 64-bit argument in RCX, and two 16-bit arguments in DX and R8W.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks. I didn't even catch that, but IFX is passing the lower 16 bits of the COORD structure in DX, and the upper 16 bits in R8W, as if they are two separate 16 bit parameters.
And thanks for that test code, that will do very nicely. I'll see if IFX does the same thing with that.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are probably aware but take care with "Console API in Kernel32" the latest Windows 11 updates by default use "Windows Terminal" rather than the classic "Windows Console Host". If The terminal type is used many Console API calls don't work (or appear to work but corrupt things that get you later) and some cause the console to close unexpectedly. I have been forced to have a fork in my software to support both options. The "new" terminal is escape sequence driven, this "new way forward" reminds me of MSDOS days in the 80s with ANSI.SYS escape sequences....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks. I had read a little bit about the new terminal. I'm still running Windows 10, and the old console host is still the default, although I do have Windows Terminal installed, but haven't played around with it too much, or tried to run any of my console programs in it.
There was also the "new console" vs the "legacy console", and I remember I had some problem with that. To get a program to run correctly I had to switch it back to legacy mode.
I have played around a bit with the escape sequences for terminal control in Linux. It's a bit cumbersome to me, although the Windows API isn't exactly non-cumbersome itself.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Okay, I created a short test program calling SetConsoleCursorPosition, and the problem occurs exactly as in the original. I'll attach the source file separately below as well as paste it right here:
----------------------------------------------------------------------------------------------
Program TestConsoleCall
Use ifcore
Use kernel32
TYPE (T_CONSOLE_SCREEN_BUFFER_INFO) :: buffinfo
TYPE (T_COORD) :: scoord
integer(HANDLE) ConHandle
Integer*4 retval
ConHandle = GetStdHandle(STD_OUTPUT_HANDLE) ! Get handle to console
retval = GetConsoleScreenBufferInfo(ConHandle, buffinfo) ! Get bufferinfo
scoord = buffinfo%dwCursorPosition ! Copy cursor coordinates to separate structure.
!Now try call in both both forms:
retval = SetConsoleCursorPosition(ConHandle, buffinfo%dwCursorPosition)
retval = SetConsoleCursorPosition(ConHandle, scoord)
End Program TestConsoleCall
------------------------------------------------------------------------------------------------------
While the SetConsoleCursorPosition is simple enough, there is no corresponding GetConsoleCursortPosition function, and you have to use GetConsoleScreenBufferInfo which returns a larger structure with the current coordinates in a substructure, %dwCursorPosition. I wondered if maybe IFX got confused by passing a member of the larger structure, so I created a separate T_COORD structure, and did two calls with each. The problem occurred in both forms, so that didn't have anything to do with it.
Disassembly of the above is as follows:
---------------------------------------------------------------------------------------------------------
scoord = buffinfo%dwCursorPosition ! Copy cursor coordinates to seperate structure.
00007FF6AAF01037 mov eax,dword ptr [BUFFINFO+4h (07FF6AAF080ACh)]
00007FF6AAF0103D mov dword ptr [SCOORD (07FF6AAF080A0h)],eax
!Now try call in both both forms:
retval = SetConsoleCursorPosition(ConHandle, buffinfo%dwCursorPosition)
00007FF6AAF01043 mov rcx,qword ptr [CONHANDLE]
00007FF6AAF01047 mov r8w,word ptr [BUFFINFO+6h (07FF6AAF080AEh)]
00007FF6AAF0104F mov dx,word ptr [BUFFINFO+4h (07FF6AAF080ACh)]
00007FF6AAF01056 call SetConsoleCursorPosition (07FF6AAF0129Ch)
00007FF6AAF0105B mov dword ptr [RETVAL],eax
retval = SetConsoleCursorPosition(ConHandle, scoord)
00007FF6AAF0105E mov rcx,qword ptr [CONHANDLE]
00007FF6AAF01062 mov r8w,word ptr [SCOORD+2h (07FF6AAF080A2h)]
00007FF6AAF0106A mov dx,word ptr [SCOORD (07FF6AAF080A0h)]
00007FF6AAF01071 call SetConsoleCursorPosition (07FF6AAF0129Ch)
00007FF6AAF01076 mov dword ptr [RETVAL],eax
-------------------------------------------------------------------
Note the copy of the Coord structure goes as expected, IFX sees that as a 32-bit structure. But in the calls to SetConsoleCursorPosition, it tries to pass it as though it is two separate 16-bit arguments.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
With this nice reproducer, I'm filing a bug report for this issue. I kinda fog over when looking at assembly code. The Fortran compiler team doesn't.
What do you mean "the output screen was corrupted"? Is that true with this reproducer?
I compiled and ran the reproducer from the oneAPI Windows command window. What should I see or not see?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You won't see anything with that test program above, it doesn't produce any output at all. It was just to see what the assembly output of IFX was and verify it was producing incorrect function call code to the "SetConsoleCursorPosition" API call. All the program does is get the current cursor position, then just set the cursor position to the original via the suspect function call.
The original program where I first noticed this with IFX basically printed some text to the console window, with some numeric fields. Then it would update some output numbers by returning the cursor to the starting position and then print out the new output. The result was a "live" looking screen with output values changing.
When I compiled and ran it with IFX, that didn't work right with the output all misaligned, and it turned out it wasn't returning the cursor to proper initial position because of this bug with the function call.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The assembly output above was just copied and pasted from the Disassembly window of the Visual Studio Debugger of the executable. I remembered that IFort can do assembler listings, and IFX will as well. But with IFX, I see it will only do one or the other. Produce an .asm or an .obj file, but not both, and the output is very barebones, no /FAs assembler with source, and uses the GAS(AT&T) syntax rather than MASM(Intel) syntax.
Anyway, I've attached the asm output of both IFort and IFX on the test program here, if anyone is interested. These were compiled with default Debug build settings of each compiler.
Well, the forum doesn't seem to like .asm files, so I changed the extension to .txt
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks! The bug ID is CMPLRLLVM-54058. I'll let you know when there's a fix!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you. I'll be interested when they fix this, and to see what was going wrong there.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please check the ifx compiler 2024.1. It was released last week. The issue you reported is fixed.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you so much for the update! Glad this bug happened to show up with me, so they could fix it.
![](/skins/images/D2683F18326913BBA0436CB7114DD569/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page