I got some huge arrays in my program. I use gfortran (tmd64-1) 4.7.1 version and I try to compile a code which begin with:
$LARGE
1
Error: Invalid character in name at (1)
but I get an above error. I use -fdollar-ok option but as far as I know, it doesn't affect first character in a symbol name. How can I pass by the problem?
Related
While trying to compile the following expression :
String.blit (String.make tfs.len ' ') 0 tfs.txt 0 tfs.len;
the compiler complains with the following error :
Error: This expression has type string but an expression was expected of type bytes
and the variable 'tfs.txt' (of type string) is pointed at.
As suggested in some forum, I tried to set the variable OCAMLPARAM to the value: safe_string=0,_
but with no result
I'm using OCaml 4.11.1 under Ubuntu 20.01.01 LTS
Since OCaml 4.10.0, the distinction between immutable string and mutable bytes is a configure-time default that cannot be changed on a program-by-program basis.
If you are trying to compile some old legacy code, it might make sense to use a version of OCaml configured without this distinction.
Otherwise, it would be more future-proof to adapt your code to use bytes when in-place mutation of strings is needed (which is not clear from your code snippet).
The following piece of code works in C++ when running on Windows:
void* paramsList[MAX_PARAMS_NUM] = { 0 };
...some code to populate paramsList (p.s MAX_PARAMS_NUM is a constant)
vsnprintf((char*)pStr, MAXLEN, (char*)pTempFormat, (va_list)paramsList);
This code works fine on Windows, but i am trying to make it run on Linux and the program crushes because this conversion of paramsList to va_list doesn't work there.
Now the setting of this scenario is that i get a format string from a server that i don't control. The format string ('pTempFormat') is like the one used in printf of unknown number of % in it (maximum is MAX_PARAMS_NUM) and i populate the paramsList accordingly and then i use vsnprintf to create a string from the format string i got and the values populated in paramsList.(those values can be anything from integers, to hex to char * (aka strings) and any combination of them, according to the format string received from the server).
i don't know how many locations paramsList to pass to vsnprintf until i finish populating it according to the format string received from the server. So i need to somehow either pass a variable number of locations from paramsListto vsnprintf or to convert those locations into va_list (which i couldn't figure out how to do from what i read online).
I also considered using a combination of variadic templates and va_list - to somehow pass a variable number of locations from paramsListto a variadic function and to pass them on to vsnprintf. But i couldn't figure out how to pass certain locations from a given array to a variadic function either.
Update:
I use Visual Studio 2015 to compile on Windows, and GCC 4.9 on Ubuntu.
The error i am getting when trying to compile this code on Linux is: error: ISO C++ forbids casting to an array type 'va_list {aka __va_list_tag [1]}'
va_list is an unspecified type. That means it may be a void* [] or something else entirely.
That it worked by chance in some cases is just that va_list is compatible with void* [] on one particular platform for one compiler, it is by no means indication that this is legal.
The correct way to deal with this is, unfortunately, to stop using the printf family and parse the format string yourself, there is no standard functionality to reach in and fetch the parsed format string to use for yourself.
When migrating from GNU FORTRAN Compiler 4.3.2 to 4.8.5 a user got an error
p.for:227.25:
write(3,446) ((r(i),ERC(i),EIC(i),ERp(i),EIp(i)),i=1,I1)
1
Error: Expected a right parenthesis in expression at (1)
Here the output list is built using the implied DO-loop construct. The error persists even when compiling with --std=legacy.
The problem is easy to fix. When I remove the parentheses around the list of array elements the code compiles and seems to work as expected.
write(3,446) (r(i),ERC(i),EIC(i),ERp(i),EIp(i),i=1,I1)
I would be content with this fix, however our users often store multiple copies of code on different systems and exchange code between them seemingly at random. On the other hand, the makefiles and build scripts are usually specific to our cluster.
It would be nice to find that there is a command line option that will let such code pass syntax checking. I could not find anything like -ffixed-parenthesized-values-in-implied-loop in the list of available GNU Fortran Compiler Language Options.
Q: Is it possible to tweak a build script to let such statement compile without modifying the source code?
I'm currently in the process of upgrading an old program written in FORTRAN and I'm trying to get it to compile using gfortran. I can get it to build, however the program now chokes on the namelists that it is reading in.
An example of a namelist that came with the program is shown below. It cannot correctly read this file due to the space between the variable name and the parenthesis. Since these files are very large, is there anyway I can tell gfortran to expect an older namelist format?
&<NAME>
<VARNAME> (1) = 0,
<VARNAME> (2) = -1e-13,
<VARNAME> (3) = 0.2983
&End
If not, I can resort to doing a search/replace but I'd rather not mess with the data and just have the code successfully read it in.
Namelist is quite complicated, as you can tell from the fact that there are 92 namelist test cases in the gfortran testsuite.
gfortran has no option to do what you ask. You will probably have to remove the blanks by hand or by sed, like Vladimir F suggested.
I might add that blanks in the subobject designator (the varname(i) part) are explicitly forbidden in the F2003 standard 10.10.1.1:
"In the input record, each object name or subobject designator may be preceded and followed by one or more optional blanks but shall not contain embedded blanks."
so this is unlikely to be changed in a future version of gfortran.
Look at this vulnerable snippet:
int main(int argc, char **argv) {
printf(argv[1], "bla");
return 0;
}
Compiling it without optimization leads to
./test "asd"
asd
./test "asd %s"
asd bla
./test "asd %0\$s"
asd %0$s
./test "asd %45\$s"
asd XDG_VTNR=7 <-- What the...
Well, actually it seems like "%(number)\$s" tries to interpret the (number)th argument as a string, looking upside the stack, and I met my environment variables. Is the use of such an format string documented anywhere, especially the use of the curious "\$" ? I couldn't find any references.
Finally, compilation with optimization enabled it leads to:
*** invalid %N$ use detected ***
asd zsh: abort ./test "asd %46\$s"
I've never seen such an error before. Where does it come from?
(I'm using Gentoo Linux / GCC 4.8.2 / glibc 2.18)
Sure, it's mentioned in the manual page like you'd expect. It seems to come from the Single Unix Specification (i.e. not C99).
It's used in internationalization, when you ofteen need to swap around the order of various pieces of information to fit the translation. The number is an argument index:
One can also specify explicitly which argument is taken, at each place where an argument is required, by writing "%m$" instead of '%' and "*m$" instead of '*', where the decimal integer m denotes the position in the argument list of the desired argument, indexed starting from 1
So in a more sensible program, this:
printf("%2$d %1$d", 1, 2);
prints
2 1
It's possible that buiding with optimizations enabled makes the compiler perform more heavy-weight analysis of the code, so that it can "know" more about the actual argument list and generate a better error.