In the program below, a strange result is obtained (z = 6.013470016999178 E+153).
At the same time, no errors are issued when compiling and running the program?
program fpu
real(8) :: f, z
!***
f = 1.0d307
z = 's'*f
print *, f
print *, z
end program fpu
The contents of the file BuildLog.htm:
Build Log
Build started: Project: FPU1, Configuration: Release|x64
Output
Deleting intermediate files and output files for project 'FPU1', configuration 'Release|x64'.
Compiling with Intel(R) Visual Fortran Compiler 19.1.3.311 [Intel(R) 64]...
ifort /nologo /Od /fpe:0 /fp:strict /fp:except /fpconstant /assume:minus0 /Qfp-stack-check /Qfp-speculation=strict /module:"x64\Release\\" /object:"x64\Release\\" /Fd"x64\Release\vc150.pdb" /check:all /libs:static /threads /c /Qlocation,link,"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.16.27023\bin\HostX64\x64" /Qm64 "C:\Users\chernov\source\repos\FPU1\FPU1\fpu.f90"
Linking...
Link /OUT:"x64\Release\FPU1.exe" /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"x64\Release\FPU1.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /SUBSYSTEM:CONSOLE /IMPLIB:"C:\Users\chernov\source\repos\FPU1\FPU1\x64\Release\FPU1.lib" -qm64 "x64\Release\fpu.obj"
Embedding manifest...
mt.exe /nologo /outputresource:"C:\Users\chernov\source\repos\FPU1\FPU1\x64\Release\FPU1.exe;#1" /manifest "x64\Release\FPU1.exe.intermediate.manifest"
FPU1 - 0 error(s), 0 warning(s)
Link Copied
/stand (-std on Linux/Mac), not /standard-semantics. The first asks the compiler to warn of any non-standard usage (keeping in mind that there are some cases it won't catch). The second alters run-time behavior from defaults that conflict with the current standard.
This is apparently one of the extensions to the standard that the Intel compiler recognises. You can force an error message by using the option "-stand", so that this type of extensions is recognised and rejected.
I'd guess that this harks back to olden days when Fortran didn't have a native character type, but you could store character data in other types.
Adding a couple of lines reveals what is going on
f = 1.0d307
z = 's'*f
print *, f
print *, z
z = z/f
write(*,*) z
write(*,'(z16)') z
Write(*,*) z
gets the real*8 equivalent of 's' which is
6.013470016999178E-154
printing the same result in hex format you get
2020202020202073
which shows you that 's' consists of 7 blanks (hex code 20) followed by the hex code for lower case s.
The result of 's'*z is what you get if you take the bit pattern corresponding to an eight character string consisting of 7 blanks and 's', and, treating it like a real*8 number, multiply that by f
You can avoid unwelcome surprises of this type by adding (or placing, as appropriate) the option /standard-semantics to the file ifort.cfg (in the same directory as the compiler driver, ifort.exe), or making a habit of selecting this option in the VS project configuration before building.
/stand (-std on Linux/Mac), not /standard-semantics. The first asks the compiler to warn of any non-standard usage (keeping in mind that there are some cases it won't catch). The second alters run-time behavior from defaults that conflict with the current standard.
the option is
-stand
on Mac and Linux these days. We are moving away from -std although it is still accepted
For more complete information about compiler optimizations, see our Optimization Notice.