- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
All,
I have some call statements that I would like to be skipped over when I am in debug mode and used when in compiling a release. I have turned FPP on.
I am trying to structure something as follows:
#ifdef DEBUG
#else
call abcd...
#endif
Is there a better way to achieve this or can it be done this way?
Thanks
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The use of #ifdef implies (requires) the use of the Fortran PreProcessor (-fpp)
If using fpp, then use fpp in Release build as well and:
#ifdef DEBUG
#define DEBUG_abcd(argX, argY) call abcd(argX, argY)
...
#else
#define DEBUG_abcd(argX, argY)
,,,
#endif
then
... ! your code
DEBUG_abcd(a, b)
''' ! more code
IOW you can define an assert and trace.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It sounds like you are in Visual Studio on WIndows. IF NOT, if you are on linux or macOS, if your filenames use upper case F, like .F90 or .F then fpp is invoked by default before the compilation.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When you conditionally compile chunks of source based on preprocessor conditionals, you accept that your program source has slightly different logic between release and debug builds. Continuing to accept that, my preference is to not use the preprocessor (which may come with a set of subjective evils) and instead make the equivalent changes directly in normal, boring, Fortran source ... IF (debug) CALL abcd(..)
This means you need some way of changing that `debug` named constant or similar between release and debug builds. One way to do this is by varying the source file for a module that contains the definition of that module between release and debug builds. For example:
! In DebugMod_debug.f90
MODULE DebugMod
IMPLICIT NONE
LOGICAL, PARAMETER :: DebugFlag = .TRUE.
INTEGER, PRIVATE :: log_unit = 0
CONTAINS
SUBROUTINE DebugLog(text, value)
CHARACTER(*), INTENT(IN) :: text
INTEGER, INTENT(IN) :: value
IF (log_unit == 0) THEN
OPEN( &
NEWUNIT=log_unit, &
FILE='MyLoggingFile.txt', &
ACTION='WRITE', &
STATUS='REPLACE' )
END IF
WRITE (log_unit, "(A,T60,I0)") text, value
END SUBROUTINE DebugLog
END MODULE DebugMod
! In DebugMod_release.f90
MODULE DebugMod
IMPLICIT NONE
LOGICAL, PARAMETER :: DebugFlag = .FALSE.
CONTAINS
SUBROUTINE DebugLog(text, value)
CHARACTER(*), INTENT(IN) :: text
INTEGER, INTENT(IN) :: value
! Do nothing
END SUBROUTINE DebugLog
END MODULE DebugMod
perhaps used in an example program...
PROGRAM MainProgram
USE DebugMod
IMPLICIT NONE
INTEGER :: value
value = 10
! Useful program logic elided...
IF (DebugFlag) THEN
IF (value == 10) PRINT *, 'All good'
END IF
! Useful program logic elided...
CALL DebugLog('The value of value ended up being ', value)
END PROGRAM MainProgram
Within Visual Studio you can use the "Exclude File From Build" file specific property to determine which source file ends up contributing the DebugMod module. In the following I am doing a Debug build, so the DebugMod_release.f90 file is excluded from the build.
Compile optimisers have been smart enough for several decades now, that they will compile time eliminate execution of IF on a constant logical value. Compilers with inter-procedural optimisation are also likely to knock out calls to a subroutine that has no effect.
The Fortran module dependency determination step of the build within Visual Studio may issue a warning about multiple files contributing the same module, but this appears to be cosmetic.
Other sane build systems will have similar mechanisms for selecting source files based on the nature of a build.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Re: "Is there a better way to achieve this or can it be done this way?," can you please explain what would constitute a "better way" for you?
If by a "better way" you mean to not needing to use a preprocessor but you do intend to stick to Intel Fortran on Windows, you can consider predefined processor symbols along with Intel's directive-enhanced compilation option.
See this link.
And consider this example that is usable from Visual Studio as well:
module m
!dir$ if defined (_DEBUG)
logical, parameter :: DEBUG = .true.
!dir$ else
logical, parameter :: DEBUG = .false.
!dir$ end if
contains
subroutine sub()
if ( DEBUG ) then
print *, "In debug mode"
end if
print *, "Hello World!"
end subroutine
end module
use m
call sub()
end
- So when DEBUG mode is not in effect, the program works as below
C:\Temp>ifort p.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.3.0 Build 20210609_000000
Copyright (C) 1985-2021 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.29.30038.1
Copyright (C) Microsoft Corporation. All rights reserved.
-out:p.exe
-subsystem:console
p.obj
C:\Temp>p.exe
Hello World!
- But with DEBUG mode, it will be like so: note no explicit prepreprocessing on your part is required.
C:\Temp>ifort /dbglibs p.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.3.0 Build 20210609_000000
Copyright (C) 1985-2021 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.29.30038.1
Copyright (C) Microsoft Corporation. All rights reserved.
-out:p.exe
-nodefaultlib:libcpmt
-subsystem:console
p.obj
C:\Temp>p.exe
In debug mode
Hello World!
![](/skins/images/C4F7392A5C68ACA60290C9576F107044/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