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

Variable not initialized in Release mode

Gian_Giuseppe_S_
Beginner
2,774 Views

I have a solution constitued by a fortran code (fortran project) that depend on a project constitued by a *.lib file.

In the fortran code, some variable are initialized in a subroutine.

In the debug mode, the software/solution is correct and all the variables can be used with the correct value.

In the release mode, any variable appear with a initial value. For example, the string variable appear with the value '        ' but in the code the same variables are correctly initialized.

Thank you in advance.

0 Kudos
12 Replies
jimdempseyatthecove
Honored Contributor III
2,774 Views

If you do not initialize the string variable yourself to ' ' you cannot rely on it being pre-initialized for you. Debug builds may initialize variables in an aid to debugging (e.g. to identify where you are using a variable before it is defined/initialized). Release mode does not do this.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
2,774 Views

Debug builds do not initialize variables, but you are perhaps more likely to find that a variable happens to have a zero value, especially if it got allocated in static memory. In release mode, with optimization, variables are more likely to be assigned to registers or the stack.

Please show us a small but complete test case that demonstrates the problem you have. It is unclear from your description what is happening.

0 Kudos
Gian_Giuseppe_S_
Beginner
2,774 Views

The variables are initialized also in the release mode. The problem is that in this mode the initialization does not seem to work correctly...

0 Kudos
Steven_L_Intel1
Employee
2,774 Views

Test case, please.

0 Kudos
mecej4
Honored Contributor III
2,774 Views

You cannot trust the debugger to show you variable values correctly when the program has been compiled with a high optimization level. In particular, as others have commented, variables currently in registers may appear to have incorrect values because the debugger shows you the contents of the memory location allocated to the variable, when the changes to the variable value have not yet been copied to memory.

0 Kudos
Gian_Giuseppe_S_
Beginner
2,774 Views

In order to explain my problem I present a case study which is not exactly my code but is an example to understand the bug that arises in my code.

I have three subroutines (for take a simplicity I omit the variable declarations):

subroutine MAIN_PROGRAM

call INIT_DATA

A=B+C;

write(*,*) "the variable A is", text,A

pause

end subroutine MAIN_PROGRAM

 

subroutine INIT_DATA

B=10.0

C=1.0

text='equal to'

end subroutine INIT_DATA

 

If I try to execute the subroutine "MAIN_PROGRAM" in debug mode, the output is correctly:

"the variable A is equal to 11.0"

In Release mode, the run of "MAIN_PROGRAM" produce the output:

"the variable A is                 11.0"

or

"the variable A is equal to 0.0"

or

"the variable A is equal to 10.0"

or

"the variable A is equal to 1.0"

Therefore , in release mode , it happens that some variables are initialized even after performing proper initialization

 

 

 

 

 

 

 

 

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,774 Views

The underlying problem is you are expecting A, B, C and text to have global scope.

Instead, each has local scope. Instead for global scope

module YourModuleName
   real :: A,B,C
   character(len=YourMaxLen) :: text
end module YourModuleName

subroutine MAIN_PROGRAM
  use YourModuleName
  implicit none
  call INIT_DATA
  A=B+C;
  write(*,*) "the variable A is", text,A
  pause
end subroutine MAIN_PROGRAM

subroutine INIT_DATA
  use YourModuleName
  implicit none
  B=10.0
  C=1.0
  text='equal to'
end subroutine INIT_DATA

A better arrangement would be to place the INIT_DATA in the module YourModuleName (name this whatever you want)

module YourModuleName
   real :: A,B,C
   character(len=YourMaxLen) :: text
contains
  subroutine INIT_DATA
    use YourModuleName
    implicit none
    B=10.0
    C=1.0
    text='equal to'
  end subroutine INIT_DATA
end module YourModuleName

subroutine MAIN_PROGRAM
  use YourModuleName
  implicit none
  call INIT_DATA
  A=B+C;
  write(*,*) "the variable A is", text,A
  pause
end subroutine MAIN_PROGRAM

Jim Dempsey

0 Kudos
Gian_Giuseppe_S_
Beginner
2,774 Views

Dear Jim,

the variables used in my code are just defined in global mode, by a module definition also if in my little example this is not evident.

Thank you,

Gian Giuseppe

0 Kudos
mecej4
Honored Contributor III
2,774 Views

The program that you displayed in #7 is not a Fortran Standard compliant complete program. The listed code does not even have a main program, so you could not have compiled and run it. If you changed Subroutine Main_Program to Program Main_Program, you could compile and run it, but its output is undefined, and it is pointless to argue what the output of that program should be. You can see this for yourself by compiling with the /CU option after changing the first subroutine to a program.

If that program was meant to present a simplified view of a real problem with a larger program, it failed. To make progress towards a solution, you will need to present actual code instead of approximate and incomplete verbal descriptions. As to the unproven claim that

"Therefore , in release mode , it happens that some variables are initialized even after performing proper initialization

I remain an unbeliever.

0 Kudos
andrew_4619
Honored Contributor III
2,775 Views

To reiterate mecej4's comment just turn your few lines of code into a proper stand alone example and then the problem will become clear and the and a proper answer can be given. 

0 Kudos
Gian_Giuseppe_S_
Beginner
2,775 Views
I try to realize a real example with the problem.

The subroutine MAIN_SOFTWARE is the main that generate a menù. By clicking the menù it is possible to run a subroutine RUN_PROGRAM.

If I try to execute this program in debug mode, the output is correctly, while in release mode the value of some variable is zero (or null, for character variables) even though in "init_data" all variables has been initialized.

module MOD_VARIABLES

  REAL A,B

  character*256 NAME_FILE

end module MOD_VARIABLES
program MAIN_SOFTWARE

 	use MOD_VARIABLES

  implicit none


	do while(.true.)
	  call YIELDQQ
	end do

end

!* The INITIALSETTINGS function initializes the menus that will appear 
!* when the program starts. It is called internally by the QuickWin
!* startup code and should never be directly called from the program.
!*
!* To debug the INITIALSETTINGS routine, put a breakpoint in the code 
!* before starting to debug.  This is necessary since the code gets

!* called before any FORTRAN code is executed.
!
!* Note how the first (menu item 0) menu item for each new menu uses 
!* NUL for the menu routine.

!* This routine demonstrates the following menu functions:


logical(KIND=4) function INITIALSETTINGS

	use DFLIB
	use DFLOGM
	use MOD_H2O

	implicit none

	character(LEN=50)mname
	integer(KIND=4)mnum
	logical(4)  l4
	external RUN_PROGRAM

	mnum=1
	mname='TEST'C
	l4 = appendmenuqq(mnum, $MENUENABLED, mname, NUL)
	mname='Run...'C
	l4 = appendmenuqq(mnum, $MENUGRAYED, mname, RUN_PROGRAM)

	InitialSettings = l4

end function INITIALSETTINGS
subroutine RUN_PROGRAM

	use MOD_VARIABLES
	
	implicit none

  real C
  
  	
	call INIT_DATA
	
	C=A+B
	
	WRITE(*,*) "The C value",NAME_FILE,C
	PAUSE


end subroutine RUN_PROGRAM

 

 

0 Kudos
mecej4
Honored Contributor III
2,775 Views

Module MOD_H2O is unknown. If the code INIT_DATA is to taken from #7, since no new version was given, the bugs are clear: the subroutine INIT_DATA uses implicit typing, and assigns a character string to a real variable, all these variables are local to the subroutine, and are not visible outside the subroutine. Setting these variables has no effect on the variables with the same names in module MOD_VARIABLES, so the module variables A, B and NAME_FILE are undefined when you attempt to use and display them in subroutine RUN_PROGRAM.

Given all these bugs, not much faith should be placed in what one sees in the debugger. As I suggested earlier, add IMPLICIT NONE to all your routines and compile with checks such as /CU turned on. Optimization can be thought of after the bugs have been fixed. Remember, Knuth is reported to have said, "Premature optimization is the root of all evil".

0 Kudos
Reply