How to get gfortran to do INTEGER - LOGICAL conversion - gfortran

According to this, gfortran can do integer-logical conversion, but I'm getting this error:
if (.not.bDropped.and.(zz_unif01() .lt. (1 - (Test_Dru
1
Error: Operand of .not. operator at (1) is INTEGER(4)
I know it would be better to change the code from .not.bDropped to (bDropped.eq.0), but that would not be simple because it's generated code.
I tried various -std=xxx flags but they made no difference.

The last line on the page you linked to reads
However, there is no implicit conversion of INTEGER values in if-statements, [...].
I'd guess that has something to do with it.
Edit: This seems not to be the entire truth. Simply doing l1 = .not. 0 (when l1 is a logical variable) gives the same error you received. So there is no implicit conversion in this case either.

Related

Lua function returns 768 values - how to put these into a table

I am programming an instrument that uses Lua with extensions for accessing the instrument controls and displays.
The instrument has a command to read the analyzer plotted points for frequency and amplitude:
:analyzer:trace:frequency?
and
:analyzer:trace:amplitude?
Whenever either of the above is executed, 768 values are returned (frequency or amplitude). This is an embedded test system running Lua for user apps - I can't change the command.
I tried to use table.pack() to put these returned values into a table, but the syntax of the command with the ":" causes an error.
Code I tried --
freq = {};
freq = table.pack(:analyzer:trace:frequency?);
Error message is -- tests.lua:2428: unexpected symbol near ':'
Whenever the :analyzer:trace:frequency? is run stand alone (from PuTTY) or as a line in the Lua code, there is no error.
PuTTY receives 768 frequency values, each separated by a comma.
Looking for ways to direct the return into an array/table or to wrap the command so that it will execute similarly as above.
Thanks

When does pthread_t have 0?

I created threads using pthread_create() in RHEL 7.2.
pthread_create returns 0, but *thread (1st parameter) is 0.
do you know the reason that thread id is 0?
pthread_t thread[6];
int nArg;
int nThread = pthread_create(&thread[0], NULL, funcA, &nArg);
if(0 > nThread)
printf("failed");
else
printf("thread started: %ld", thread[0]);
Output:
thread started: 0
I created threads using pthread_create() in RHEL 7.2. pthread_create
returns 0, but *thread (1st parameter) is 0.
do you know the reason that thread id is 0?
Assuming for the moment that it really is 0, what of it? That presupposes that pthread_t is an arithmetic type, which is not specified by the current version of POSIX, but if so, then 0 is a valid value for it. There is no documented significance for specific thread identifier values, and in particular, there is no reason to think that a thread shouldn't be assigned 0 as its identifier if that is a valid value of type pthread_t.
Since you also mentioned the return value of pthread_create, I suppose you may think there is some kind of relationship between that and the thread ID. No such relationship is documented, except that the value of the thread ID is defined after pthread_create() returns only if the return value is exactly 0.
But that does point to an issue in your code, which #ErikAlapää first pointed out: pthread_create() is in the group of functions that return an error number directly on failure, not the group that return -1 on failure and expect you to consult errno for the error number. Error numbers are positive, so your condition if(0 > nThread) cannot be relied upon to detect whether pthread_create failed. You should test against exactly 0:
if (0 != nThread) {
printf("failed");
} else {
printf("thread started: %lu", (unsigned long) thread[0]);
}
Note also the format change and cast in the second printf() call. You need the second argument to have exactly the type corresponding to formatting directive (formerly %ld, but now %lu) and that's unsigned long int. The cast is valid is long as pthread_t is an arithmetic or pointer type, and in practice, the compiler can be relied upon to reject the code if it's anything else -- a structure type, say. Given that a cast is necessary (but possibly not sufficient) to obtain a known type, an unsigned type is safer because the conversion then has defined behavior in the event that the original value is out of range for the target type. If you have a type mismatch, as you could have had in your original code, then the behavior is undefined, and among the more likely of the uncountably many possible manifestations of such UB is that "0" is printed despite thread[0] being nonzero.
With all that said, I do not reproduce your issue, even with your original, flawed code. I'm inclined to suspect that your pthread_create call is failing, possibly because you're using a C library built without thread support, or linking dummy pthreads routines instead of functional ones. Be sure when you build to provide the right options for a pthreads program. For example, if you're compiling with gcc then you would want to provide the -pthread option. If you have separate compilation and link steps, then use that option for both.
Try instead checking the return value against exactly zero. Only if return value is 0 did the thread creation succeed.
The errno manpage says 'Valid error numbers are all positive numbers'. For example, on Linux, the errno error numbers seem to be roughly betwen 0 and 200.
Also, print the message corresponding to the errno error number you get, using e.g. perror().
The pthread_t type is opaque according to POSIX. It can be any type. In particular, it is not required to be an arithmetic type (pointer or integer). A conforming implementation of POSIX threads can use a struct for pthread_t.
If pthread_t happens to be an integer type, there is no prohibition against it being zero. It could be the index of a thread in some array, such that the first thread gets position zero.
We are not surprised that the standard input file descriptor is zero, after all.

E2099 Overflow in conversion or arithmetic operation

I want to compare an int64 with a variable like this:
const GB=1073741824;
if DiskFile.Size< 1*GB then
It works with 1 but not with 3:
if DiskFile.Size< 3*GB then
This post (Strange Delphi integer multiplication behavior) explains why. I agree with that explanation. The result of 2*GB cannot fit in 'integer'. What I don't understand is why the compiler chooses integer instead the int64? As in the case of:
if DiskFile.Size< 3073741824 then <--------- almost 3GB
that works.
There is any way to write the last line of code in the 3*GB style (using constants) BUT without defining a new constant for 1GB, 2GB, 3GB, 4GB, etc ?
The first thing to be clear of here is that the integer overflow occurs in the compiler. The compiler has to evaluate your expression because it is a constant expression and they are evaluated by the compiler.
The documentation is a little sparse (and I am being kind here) on how the compiler treats your expression. We can infer, at least empirically, that the compiler attempts to perform 3*GB in a signed integer context. That is clear from the error message.
You need to force the compiler to evaluate the expression in an Int64 context. A cast will force that:
if DiskFile.Size< Int64(3)*GB then
....
Another option is to make the constant have type Int64:
const
GB = Int64(1073741824);
Although I think I'd write it like this:
const
KB = Int64(1024);
MB = 1024*KB;
GB = 1024*MB;
So long as GB is a 64 bit type then you can revert to:
if DiskFile.Size < 3*GB then
....
I'd like to elaborate on my second paragraph above. How can we tell that the compiler performs the arithmetic in 32 bit signed integer context? The following program suggests that this is so:
{$APPTYPE CONSOLE}
const
C1 = 715827882; // MaxInt div 3
C2 = C1+1;
begin
Writeln(3*C1);
Writeln(3*C2);
Readln;
end.
The first expression, 3*C1 compiles, the second fails with E2099. The first expression does not overflow a signed 32 bit integer, the second does.
When looking at the documentation, it is unclear whether the true constant 1073741824 should be of type Integer or Cardinal. The compiler could choose either. It seems that the compiler, when presented with a choice between signed and unsigned types, chooses signed types.
But then one might imagine that the following program would behave in the same way, but with Smallint and Word taking the place of Integer and Cardinal:
{$APPTYPE CONSOLE}
const
C1 = 10922; // high(Smallint) div 3
C2 = C1+1;
begin
Writeln(3*C1);
Writeln(3*C2);
Readln;
end.
But no, this program compiles. So, at this point I am giving up on the documentation which appears to bear little relationship to the actual behaviour of the compiler.
My best guess is that a integral true constant is handled as follows:
If it is within the range of Integer, it is of type Integer.
Otherwise, if it is within the range of Cardinal, it is of type Cardinal.
Otherwise, if it is within the range of Int64, it is of type Int64.
Otherwise, if it is within the range of UInt64, it is of type UInt64.
Otherwise it is a compiler error.
Of course, all of this assumes that the compilers rules for evaluating constant expressions follow the same rules as the rest of the language. I'm not certain that is the case.

Calculating factorial on FORTRAN with integer variables. Memory overflow

I'm doing a program with FORTRAN that is a bit special. I can only use integer variables, and as you know with these you've got a memory overflow when you try to calculate a factorial superior to 12 or 13. So I made this program to avoid this problem:
http://lendricheolfiles.webs.com/codigo.txt
But something very strange is happening. The program calculates the factorial well 4 or 5 times and then gives a memory overflow message. I'm using Windows 8 and I fear it might be the cause of the failure, or if it's just that I've done something wrong.
Thanks.
Try compiling with run-time subscript checking. In Fortran segmentation faults are generally caused either by subscript errors or by mismatches between actual and dummy arguments (i.e., between arguments in the call to a procedure and the arguments as declared in the procedure). I'll make a wild guess from glancing at your code that you have have a subscript error -- let the compiler find it for you by turning on run-time subscript checking. Most Fortran compilers have this as an compilation option.
P.S. You can also do calculations like this by using already written packages, e.g., the arbitrary precision arithmetic software of David Bailey, et al., available in Fortran 90 at http://crd-legacy.lbl.gov/~dhbailey/mpdist/
M.S.B.'s answer has the gist of your problem: your array indices go out of bounds at a couple of places.
In three loops, cifra - 1 == 0 is out of bounds:
do cifra=ncifras,1,-1
factor(1,cifra-1) = factor(1,cifra)/10 ! factor is (1:2, 1:ncifras)
factor(1,cifra) = mod(factor(1,cifra),10)
enddo
! :
! Same here:
do cifra=ncifras,1,-1
factor(2,cifra-1) = factor(2,cifra)/10
factor(2,cifra) = mod(factor(2,cifra),10)
enddo
!:
do cifra=ncifras,1,-1
sumaprovisional(cifra-1) = sumaprovisional(cifra-1)+(sumaprovisional(cifra)/10)
sumaprovisional(cifra) = mod(sumaprovisional(cifra),10)
enddo
In the next case, the value of cifra - (fila - 1) goes out of bounds:
do fila=1,nfilas
do cifra=1,ncifras
! Out of bounds for all cifra < fila:
sumando(fila,cifra-(fila-1)) = factor(1,cifra)*factor(2,ncifras-(fila-1))
enddo
sumaprovisional = sumaprovisional+sumando(fila,:)
enddo
You should be fine if you rewrite the first three loops as do cifra = ncifras, 2, -1 and the inner loop of the other case as do cifra = fila, ncifras. Also, in the example program you posted, you first have to allocate resultado properly before passing it to the subroutine.

Use of selected_real_kind in Fortran to achieve desired minimum precision

I am using gfortran 4.7.1 on Mac OS X 10.8 to compile a simple program using a specific precision:
program simple
implicit none
integer, parameter :: l = selected_real_kind(18,100)
real(kind=l) :: myNum
myNum = 0.123456789123456789
print '(f18.12)', myNum
end program simple
When I compile and run I get 0.123456791043 which obviously indicates I'm not getting the precision I called for.
However if I compile with -fdefault-real-8 I get the right answer. Obviously, I could just move on and use the option, but I can't help wondering whether this is a bug or I am missing some justification. Do I really have to specify my real size outside of the code itself when it seems that selected_real_kind intent is to allow the code to specify precision?
Sorry. You have to add _l to the number assignment.

Resources