I am attempting to update a piece of fortran code that makes a calculation based on inputs from an IDL routine. When the IDL routine makes a call to fortran, it passes along the reference for each variable (IDL CALL_EXTERNAL documentation). The fortran code currently attempts to pass along each reference in the input array to a different subroutine along with the %VAL() tags.
subroutine full_calc(argc, argv)
implicit none
integer*8 :: argc
integer*8, dimension(24) :: argv
call map_gen(%VAL(argv(1)), %VAL(argv(2)), ...)
end subroutine full_calc
This worked fine with the previous code, as it was compiled in such a way as for this to be useful; however, the new compiler gives a warning that I am passing an INTEGER(8) instead of the correct type of the variables. Also, according to this, using %VAL is somewhat dubious.
If this might cause problems, what can I use to get at the values that won't throw warnings everywhere, doesn't require me to have a routine simply for passing along the references, or will at least work on any compiler?
Also, if anyone can just clarify what is really going on here or why, I would appreciate that too.
Related
My goal is to print out the string when it is defined. First of all, my code is:
program test
use, intrinsic :: iso_fortran_env, only : stderr=>error_unit
implicit none
character(len=1024) :: file_update
write (stderr, '(a)') 'file-update: '//file_update
end program test
When I run the above code, the output is:
file-update: �UdG��tdG�|gCG��m�F� dCG� ��3���3�P��3��UdG� �eG���eG�1
DG��UdG���g��<�CG�U��B�jdG�DG����3����3��cCG����3��dCG�<�CG����3������jdG�DG�0fCG�<�CG�0��F���G��G����F�pdG�1
DG�XmdG��pdG�ȡeG�0��F�p��3�XsdG����3����F��G����F��G��pdG�1
DG�XmdG��pdG�ȡeG�0��F�p��3�XsdG����3��7�G�
which means the variable file_update is not defined.
What I want to achieve is add an if...else... condition to judge if the string file_update is defined or not.
program test
use, intrinsic :: iso_fortran_env, only : stderr=>error_unit
implicit none
character(len=1024) :: file_update
if (file_update is defined) then
write (stderr, '(a)') 'file-update: '//file_update
else
write (stderr, '(a)') 'file-update: not defined'
end if
end program test
How can I achieve this?
There is no way within a Fortran program to test whether an arbitrary variable is undefined. It is entirely the programmer's responsibility to ensure that undefined variables are not referenced.1 Recall that "being undefined" or "becoming undefined" doesn't mean that there is a specific value or state we can test against.
You may be able to find a code analysis tool which helps2 you in your assurance but still it remains your problem to write Fortran correctly.
How do you carefully write code to ensure you haven't referenced something you haven't defined?
Be aware as a programmer what actions define a variable or cause it to become undefined after you defined it.
Use default or explicit initialization to ensure a variable is initially defined, or early assignment to give it a value before you use it.
With the previous, use sentinel/guard values such as values out of normal range (including NaNs).
Using allocatable (or perhaps pointer) variables.
Your compiler may be able to help, with certain options, by initializing variables to requested sentinel values for you, automatically.
Let's look at the specific case of the question. Here, we have a character variable we want to use.
As a programmer we know we haven't yet given it a value by the time we reach the point we want to use it. We could give it an initial value which is a sentinel:
character(len=1024) :: file_update = ""
or assign such a sentinel value early on:
character(len=1024) :: file_update
file_update = ""
Then when we come to look at using the value we check it:
if (file_update=="") then
error stop "Oops"
end if
(Beware such initialization in the first use here when there may be a second run through this part of code. Initialization is applied exactly once: initially.)
Which brings us to the first point above. What defines a variable? As a Fortran programmer you need to know this. Consider the program:
implicit none
character(255) name
read *, name
print *, name
end
When we reach the print statement, we've defined the name variable, right? We asked the user for a value, we got one and defined name with it, surely?
Nope.
We possibly did, but we can't guarantee that. We can't ask the compiler whether we did.
Equally, you must know what undefines a variable. There are easy cases, such as a dummy argument which is intent(out), but less obvious cases. In
print *, F(Z) + A
for F a function then perhaps Z becomes undefined as a result of this statement. It's your responsibility to know whether that happens, not the compiler's. There is no way in Fortran to ask whether Z became undefined.
The Fortran standard tells you what causes a variable to become defined or undefined, to always be defined, or to be initially defined or undefined. In Fortran 2018 that's 19.6.
Which, finally, brings me to the final point: allocatable variables. You can always (ignoring the mistakes of Fortran 90) ask whether an allocatable variable is allocated:
implicit none
character(:), allocatable :: name
! Lots of things, maybe including the next line
name = "somefile"
if (.not.allocated(name)) error stop "No name given"
...
Scalars can be allocatable, and their allocation status can be queried to determine whether the variable is allocated or not. An allocatable variable can be allocated but not defined, but using an allocatable variable covers many of those cases where a non-allocatable variable would be undefined by having an allocation status we can query: an allocatable variable is initially not allocated, becomes not allocated when associated with an intent(out) dummy, and so on.
1 A variable being undefined because "you haven't given it a value yet since the program started" is an easy case. However, a lot of the times a variable becomes undefined, instead of being initially undefined, relate to making the compiler's life easier or allowing optimizations: placing a requirement to detect and respond to such cases is counter to that.
2 No tool can detect all cases of referencing an undefined variable for every possible program.
I am starting out learning Rust macros, but the documentation is somewhat limited. Which is fine — they're an expert feature, I guess. While I can do basic code generation, implementation of traits, and so on, some of the built-in macros seem well beyond that, such as the various print macros, which examine a string literal and use that for code expansion.
I looked at the source for print! and it calls another macro called format_args. Unfortunately this doesn't seem to be built in "pure Rust" the comment just says "compiler built-in."
Is it possible to write something as complex as print! in a pure Rust macro? If so, how would it be done?
I'm actually interested in building a "compile time trie" -- basically recognizing certain fixed strings as "keywords" fixed at compile time. This would be performant (probably) but mostly I'm just interested in code generation.
format_args is implemented in the compiler itself, in the libsyntax_ext crate. The name is registered in the register_builtins function, and the code to process it has its entry point in the expand_format_args function.
Macros that do such detailed syntax processing cannot be defined using the macro_rules! construct. They can be defined with a procedural macro; however, this feature is currently unstable (can only be used with the nightly compiler and is subject to sudden and unannounced changes) and rather sparsely documented.
Rust macros cannot parse string literals, so it's not possible to create a direct Rust equivalent of format_args!.
What you could do is to use a macro to transform the function-call-like syntax into something that represents the variadic argument list in the Rust type system in some way (say, as a heterogeneous single-linked list, or a builder type). This can then be passed to a regular Rust function, along with the format string. But you will not be able to implement compile-time type checking of the format string this way.
I have a .exe file and i want to list all function of it. It is possible and have some tool to do it?
P/s: i tried with IDA but it is difficult to understand it. Can it resolve my problem?.
To achieve this, you must have a very good understanding of Assembly Language, and maybe learning from NASM documentation and the Intel Instruction set will get you to a good level. Before you can continue in this path.
Furthermore, for those who already know little or more Assembly Language, is possible to call the function of an exe, mostly if they are standalone or doesn't depend on any other functions using something like Asmjit. And also you can get this function addresses, and cast them into functions if you know the calling convention used here. For example, __stdcall, __cdecl and others. And if then you know the calling convention, you can use this to construct the function signature, including the return type, usually through the POP, RETURN instruction or the registry that was affected before the function exit, or return to the caller.
You have to find a good debugger, to help you find all this. As you said IDA is good but too complicated, so you can use something like x86dbg, or others like ollyDbg those can help you find the entry point of those functions and use that to construct the signature
so a core like this, assuming that 0x749593 is an address of a a function with maybe takes two argument and return sum.
typedef int (*sum)(int first, int second);
Sum mySumFunc;
Changing the address of mySumFunc to point to 0x749593, you can call this function mySumFunc(arg1, arg2 ) and it will still work.
How can I retrieve the type of architecture (linux versus Windows) in my fortran code? Is there some sort of intrinsic function or subroutine that gives this information? Then I would like to use a switch like this every time I have a system call:
if (trim(adjustl(Arch))=='Linux') then
resul = system('ls > output.txt')
elseif (trim(adjustl(Arch))=='Windows')
resul = system('dir > output.txt')
else
write(*,*) 'architecture not supported'
stop
endif
thanks
A.
The Fortran 2003 standard introduced the GET_ENVIRONMENT_VARIABLE intrinsic subroutine. A simple form of call would be
call GET_ENVIRONMENT_VARIABLE (NAME, VALUE)
which will return the value of the variable called NAME in VALUE. The routine has other optional arguments, your favourite reference documentation will explain all. This rather assumes that you can find an environment variable to tell you what the executing platform is.
If your compiler doesn't yet implement this standard approach it is extremely likely to have a non-standard approach; a routine called getenv used to be available on more than one of the Fortran compilers I've used in the recent past.
The 2008 standard introduced a standard function COMPILER_OPTIONS which will return a string containing the compilation options used for the program, if, that is, the compiler supports this sort of thing. This seems to be less widely implemented yet than GET_ENVIRONMENT_VARIABLE, as ever consult your compiler documentation set for details and availability. If it is available it may also be useful to you.
You may also be interested in the 2008-introduced subroutine EXECUTE_COMMAND_LINE which is the standard replacement for the widely-implemented but non-standard system routine that you use in your snippet. This is already available in a number of current Fortran compilers.
There is no intrinsic function in Fortran for this. A common workaround is to use conditional compilation (through makefile or compiler supported macros) such as here. If you really insist on this kind of solution, you might consider making an external function, e.g., in C. However, since your code is built for a fixed platform (Windows/Linux, not both), the first solution is preferable.
When using the following to compute PI in fortran77, will the compiler evaluate this value or will it be evaluated at run time?
PI=4.D0*DATAN(1.D0)
EDIT: depends on the compiler: see my EDIT below. EDIT END
i second Mick Sharpe's suggestion that it will be evaluated at runtime. just out of curiosity, i compiled PI=4.D0*DATAN(1.D0) with Silverfrost's ftn77 compiler and looked at the generated binary. the relevant part looks like so:
fld1 ; push 1.D0 onto the FPU register stack
call ATAN_X
fmul dbl_404000 ; multiply by 4.D0
so indeed, no compiler cleverness here.
this of course might be different with another compiler (eg. g77). EDIT: apparently, with g77 (the fortran77 front-end for gcc) it is possible (and enabled by default) to use gcc's built-in atan function to auto-fold PI=4.D0*DATAN(1.D0) into a constant. EDIT END
Calls to math functions are normally evaluated at run time. After all, there's nothing to stop you writing your own math functions. This would not be possible if they were evaluated at compile time.