Open modelica-trac-importer opened 5 years ago
Comment by sjoelund.se on 24 Apr 2017 10:09 UTC
Passing external 0
would require a change in the grammar. Passing NULL
or NULL()
would not (you can pass any expression you like according to the grammar).
I don't see why tools should be forced to generate C code in order to "just" get a warning for the hack instead of an error when compiling the code.
Well, it's using "FORTRAN 77" and not even C, so I suppose we should be happy that we can call it from C without weird Fortran wrappers, marshalling, etc...
Note: If solving the issue by creating wrapper functions and linking lapack directly in MSL to avoid passing NULL or function pointers, I think I would prefer using lapacke over clapack (since it is maintained and not an f2c hack; it does have the disadvantage of perhaps not providing lapack symbols for older MSL although these could be added).
Modified by beutlich on 24 Apr 2017 11:07 UTC
Comment by beutlich on 25 Apr 2017 08:27 UTC What is the aim of this ticket?
Comment by henrikt on 25 Apr 2017 13:17 UTC
The aim is 1; make it possible to call dgees
with "N" in a clean way that will work also for tools that generate C++ code. The description explicitly excludes alternative 2.
Comment by choeger on 25 Apr 2017 15:38 UTC I do not think that this is a very good idea. We would introduce a literal that can only be used in some calls to external functions. I think that precisely this sort of special cases makes the language hard to implement.
IMO, a better way is to use the existing external function interface and create an external object that is the NULL pointer. Is there any reason against this?
Comment by anonymous on 25 Apr 2017 15:51 UTC Passing a variable which is void* in C++ is an error for function pointer expected. Passing NULL is allowed.
Comment by dag on 26 Apr 2017 07:31 UTC
Well, NULL
often has some problems in C++. I would in that case suggest the literal 0
which can always be converted to a null pointer, or in modern versions of C++ the new keyword nullptr
.
However, going back to the original proposal -- why do you need external 0
? Wouldn't the perfectly legitimate (integer) literal 0
do the job? Assuming that the tool passes it through as a literal.
Comment by sjoelund.se on 26 Apr 2017 07:53 UTC Replying to [comment:7 dag]:
Well,
NULL
often has some problems in C++. I would in that case suggest the literal0
which can always be converted to a null pointer, or in modern versions of C++ the new keywordnullptr
.However, going back to the original proposal -- why do you need
external 0
? Wouldn't the perfectly legitimate (integer) literal0
do the job? Assuming that the tool passes it through as a literal.
For C++, you need a function prototype in order to call a function. This is automatically generated by a Modelica tool in some cases. Passing the literal 0 would mean generating int
in the interface, which is not the same length as a function pointer (on e.g. x86 64-bit platforms).
This could be solved by using external "C"
instead of Fortran 77, and knowing which LAPACK interface to compile against...
Comment by choeger on 26 Apr 2017 08:39 UTC Let me reiterate the discussion:
I think that 2. is way too specific for a change to the grammar. IMO, the only way that could be worth the effort would be to introduce generic Fortran/C/C++ literals:
This is a slightly more general change with basically the same effort w.r.t. the specification. It requires a MCP.
As a side note: What prevents users from wrapping the function into one that automatically adds the NULL argument?
Comment by henrikt on 26 Apr 2017 08:41 UTC Replying to [comment:8 Martin Sjölund]:
Replying to [comment:7 dag]:
Well,
NULL
often has some problems in C++. I would in that case suggest the literal0
which can always be converted to a null pointer, or in modern versions of C++ the new keywordnullptr
.However, going back to the original proposal -- why do you need
external 0
? Wouldn't the perfectly legitimate (integer) literal0
do the job? Assuming that the tool passes it through as a literal.For C++, you need a function prototype in order to call a function. This is automatically generated by a Modelica tool in some cases. Passing the literal 0 would mean generating
int
in the interface, which is not the same length as a function pointer (on e.g. x86 64-bit platforms).
I don't think there is a need to specify whether a tool should generate 0
, NULL
, or nullptr
; what we need is a way to specify that the external function should be called with a null pointer.
Comment by henrikt on 26 Apr 2017 08:51 UTC Replying to [comment:5 choeger]:
IMO, a better way is to use the existing external function interface and create an external object that is the NULL pointer. Is there any reason against this?
See comment:17 and comment:9. We don't have a way to pass external object pointers to to external FORTRAN 77 functions, and even if we did, the pointer would be of mismatching type void*
(error in C++).
Comment by dag on 26 Apr 2017 08:53 UTC Replying to [comment:9 choeger]:
As a side note: What prevents users from wrapping the function into one that adds the NULL argument?
Excellent point. Doesn't that solve the problem in the relatively few cases we are concerned with?
Comment by henrikt on 26 Apr 2017 08:55 UTC Replying to [comment:9 choeger]:
As a side note: What prevents users from wrapping the function into one that automatically adds the NULL argument?
Comment by choeger on 26 Apr 2017 09:07 UTC Replying to [comment:13 Henrik Tidefelt]:
Replying to [comment:9 choeger]:
As a side note: What prevents users from wrapping the function into one that automatically adds the NULL argument?
If I understand the discussion correctly, the issue with a C wrapper stems from different Fortran implementations. Now I am even more convinced that adding special syntax for this case is a bad idea. Either we do it right and extend Modelica's FFI in a more general way or we should leave the grammar untouched.
The correct solution for now seems to be to provide a ModelicaExternalFortran library that contains the required wrapper.
Comment by hansolsson on 11 May 2017 13:28 UTC For the specification this is clearly an enhancement.
Modified by beutlich on 6 Oct 2017 06:11 UTC
Comment by hansolsson on 19 Oct 2017 08:34 UTC Martin: One possibility is to just use C-version of Lapack Hans: Another possibility is to provide a few C-macros so that one can write the C-wrapper calling Fortran as an include-annotation in Modelica (name mangling and more?); see f2c.h
Martin S: Explained by NULL() in external call does not influence grammar, but need separate semantics.
Poll for possibilities:
Comment by hansolsson on 19 Oct 2017 09:01 UTC Hans: NullFunction() for generating Null-pointer to function (all capital smells like C-macro). According to Martin S all function pointers are the same size. Otto: There are embedded systems where function pointers are different in size from normal pointers - but perhaps without Fortran-library.
Henrik: A bit dangerous to derive prototypes from the call. Hans: It's possible to avoid deriving prototypes - but then C-macros for calling Fortran seems required.
Modified by beutlich on 10 Jan 2018 08:23 UTC
Reported by henrikt on 24 Apr 2017 08:51 UTC The current hack (mentioned in #960) for calling the external FORTRAN
dgees
fromModelica.Math.Matrices.LAPACK.dgees
results in code that is not legal C++ since the pointer types don't match. I don't see why tools should be forced to generate C code in order to "just" get a warning for the hack instead of an error when compiling the code.Since generating FORTRAN functions that can be passed via function pointers to in external FORTRAN calls would require considerable design work as well as work on the part of the tool vendors, it would be more reasonable to just provide a way to pass a null pointer to external functions.
The null pointer would not need to be a Modelica value, not be stored, not have a type, etc. All that we would need is a way to indicate where a null pointer is to be passed in the argument list of an external function call.
To start the discussion, I propose the following syntax:
Using
external 0
instead of, for instance,NULL
avoids the need to introduce a new keyword.Migrated-From: https://trac.modelica.org/Modelica/ticket/2183