[R-pkg-devel] warning: type of ‘zhpevx_’ does not match original declaration [-Wlto-type-mismatch]

Tomas Kalibera tom@@@k@||ber@ @end|ng |rom gm@||@com
Tue Dec 15 13:01:25 CET 2020


Dear Pierre,

your code checks fine on my Ubuntu 20.04 (gcc/gfortran 9.3), but I can 
reproduce what you are seeing on Debian 10 with gcc 8.3.

There seem to be two problems.

The first one is that the hidden character length arguments are signed, 
they are of type "long int" (not "size_t"). This is compiler specific 
and can (and does) change between Fortran compiler versions and I think 
you can just ignore it. R assumes the type is "size_t", which happens to 
be correct for newer compilers. The signedness mismatch in this case is 
benign. FC_LEN_T is defined in R, so if anywhere, this would have to be 
fixed in R, but we cannot realistically know what the type is for each 
compiler.

The second problem is that gcc/LTO is complaining about incompatibility 
between Rcomplex and "COMPLEX*16" types. This was rather tedious to 
find, I had to minimize the example for that a bit more (remove the 
Fortran code, just left the subroutine taking the same args, and then 
removing the args one by one - this is what I meant by minimizing the 
example). I don't know why the mismatch is reported. Gcc 9.3 is happy.

I would recommend to use a newer compiler, at least for these checks. 
The warnings have improved (become more informative), you can use 
-fc-prototypes-external to see what the types should be exactly for your 
compiler, and perhaps some of the warnings were false positives and have 
been fixed since.

If you want to stick to the FC_LEN_T and similar macros, I would 
recommend to check how R does it so that the code compiles also when the 
extra hidden length arguments are not used by the compiler. Still, a 
portable way to solve these issues would be via iso_c_binding, with 
FC_LEN_T we are relying on undocumented/not-standardized behavior of the 
compiler.

Best,
Tomas





On 12/15/20 7:56 AM, Pierre Lafaye de Micheaux wrote:
> Dear Tomas,
>
> Apologies for the very long delay.
>
> I was able to create a minimal version of the package (attached) that 
> gives the same exact warnings:
>
> myzhpevx.cpp:22:16: warning: type of ‘zhpevx_’ does not match original 
> declaration [-Wlto-type-mismatch]
>            void F77_NAME(zhpevx)(char *jobz, char *range, char *uplo,
>                 ^
> zhpevx.f:232:14: note: type mismatch in parameter 20
>        SUBROUTINE zhpevx(JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU,
>               ^
> zhpevx.f:232:14: note: type ‘long int’ should match type ‘size_t’
> zhpevx.f:232:14: note: ‘zhpevx’ was previously declared here
> zhpevx.f:232:14: note: code may be misoptimized unless 
> -fno-strict-aliasing is used
>
> I am under the impression that I am following quite closely what is 
> written here: 
> https://cran.csiro.au/doc/manuals/r-patched/R-exts.html#Fortran-character-strings
>
> I tried many different things but I always end up with the same main 
> warning (i.e., type of ‘zhpevx_’ does not match original declaration ).
>
> My version of fortran: GNU Fortran (Debian 8.3.0-6) 8.3.0 under Debian 10.
>
> Thank you very much for any further help you could provide so that I 
> could have my package back to the CRAN.
>
> Kind regards,
> Pierre L.
>
>
> ------------------------------------------------------------------------
> *From:* Tomas Kalibera <tomas.kalibera using gmail.com>
> *Sent:* Tuesday, 7 July 2020 15:43
> *To:* Pierre Lafaye de Micheaux <lafaye using unsw.edu.au>
> *Cc:* r-package-devel using r-project.org <r-package-devel using r-project.org>
> *Subject:* Re: [R-pkg-devel] warning: type of ‘zhpevx_’ does not match 
> original declaration [-Wlto-type-mismatch]
> My recommendation would be to try to minimize the example (package) as 
> much as possible so that it still has the problem, and then try to 
> investigate why exactly/where is the type mismatch. This is what 
> helped me debug similar issues - sometimes it was hard to tell from 
> the Fortran warnings where exactly the mismatched declarations were 
> and why they were mismatched.
>
> This process of minimization can already reveal the true source of the 
> problem, and if not, others may try to debug for you using the minimal 
> example. A useful tool is the Fortran option -fc-prototypes-external 
> (see WRE for more details) and I've also used dumps of the compiler 
> tree before (-fdump-tree-all, more in GCC documentation).
>
> Best
> Tomas
>
> On 7/7/20 5:00 AM, Pierre Lafaye de Micheaux wrote:
>> My file myzhpevx.cpp starts with:
>>
>> <quote>
>> #define USE_FC_LEN_T
>> #include <R.h>
>> #include "Rmath.h"
>>
>> #ifdef FC_LEN_T
>> extern "C" {
>>
>>    void zhpevxC(char **jobz, char **range, char **uplo, int *n, Rcomplex *ap,
>>       double *vl, double *vu, int *il, int *iu, double *abstol, int *m,
>>       double *w, Rcomplex *z, int *ldz, Rcomplex *work, double *rwork,
>>       int *iwork, int *ifail, int *info) {
>>
>>            void F77_NAME(zhpevx)(char *jobz, char *range, char *uplo,
>>        const int *n, Rcomplex *ap, const double *vl,
>>        const double *vu, const int *il, const int *iu,
>>        const double *abstol, int *m, double *w,
>>        Rcomplex *z, const int *ldz, Rcomplex *work, double *rwork,
>>        int *iwork, int *ifail, int *info,
>>        FC_LEN_T jobz_len,  FC_LEN_T range_len,  FC_LEN_T uplo_len);
>> </quote>
>>
>> So if I understand correctly what you are saying, you suggest that FC_LEN_T was not correctly defined by the CRAN team?
>>
>> Should I just write something like (adding the middle instruction below to my existing code above)?:
>>
>> <quote>
>> #ifdef FC_LEN_T
>> typedef long long int FC_LEN_T;
>> extern "C" {
>> </quote>
>>
>> Thank you
>> Pierre
>> ________________________________
>> From: William Dunlap<wdunlap using tibco.com>  <mailto:wdunlap using tibco.com>
>> Sent: Tuesday, 7 July 2020 11:46
>> To: Pierre Lafaye de Micheaux<lafaye using unsw.edu.au>  <mailto:lafaye using unsw.edu.au>
>> Cc: Ivan Krylov<krylov.r00t using gmail.com>  <mailto:krylov.r00t using gmail.com>;r-package-devel using r-project.org  <mailto:r-package-devel using r-project.org>  <r-package-devel using r-project.org>  <mailto:r-package-devel using r-project.org>
>> Subject: Re: [R-pkg-devel] warning: type of �zhpevx_� does not match original declaration [-Wlto-type-mismatch]
>>
>> With gcc 8.3.0, gfortran 8.3.0, and ld 2.33.1 from the mingw64 part of
>> rtools40 on Windows, if I misdefine the typedef FC_LEN_T and use the
>> -flto flag I get the sort of error messages that you report.
>>
>> c:\tmp\fortran>cat main.c
>> #include <string.h>
>> #include <stdio.h>
>>
>> #ifdef USE_INT
>> typedef int FC_LEN_T;
>> #endif
>> #ifdef USE_LONG
>> typedef long int FC_LEN_T;
>> #endif
>> #ifdef USE_LONG_LONG
>> typedef long long int FC_LEN_T;
>> #endif
>>
>> extern void sub_(char* word, double *ret, FC_LEN_T word_len);
>>
>> int main(int argc, char* argv[])
>> {
>>      if (argc == 2) {
>>          double ret = 3. ;
>>          FC_LEN_T word_len = strlen(argv[1]);
>>          sub_(argv[1], &ret, word_len);
>>          printf("sizeof(FC_LEN_T)=%d, ret=%g\n", (int)(sizeof(FC_LEN_T)), ret);
>>          return 0;
>>      } else {
>>          return -1;
>>      }
>> }
>>
>> c:\tmp\fortran>gcc  -flto -DUSE_INT main.c sub.f -lgfortran
>> main.c:14:13: warning: type of 'sub_' does not match original
>> declaration [-Wlto-type-mismatch]
>>   extern void sub_(char* word, double *ret, FC_LEN_T word_len);
>>               ^
>> sub.f:1:1: note: type mismatch in parameter 3
>>         subroutine sub(word, ret)
>>   ^
>> sub.f:1:1: note: type 'long long int' should match type 'FC_LEN_T'
>> sub.f:1:1: note: 'sub' was previously declared here
>> sub.f:1:1: note: code may be misoptimized unless -fno-strict-aliasing is used
>>
>> c:\tmp\fortran>gcc  -flto -DUSE_LONG main.c sub.f -lgfortran
>> main.c:14:13: warning: type of 'sub_' does not match original
>> declaration [-Wlto-type-mismatch]
>>   extern void sub_(char* word, double *ret, FC_LEN_T word_len);
>>               ^
>> sub.f:1:1: note: type mismatch in parameter 3
>>         subroutine sub(word, ret)
>>   ^
>> sub.f:1:1: note: type 'long long int' should match type 'FC_LEN_T'
>> sub.f:1:1: note: 'sub' was previously declared here
>> sub.f:1:1: note: code may be misoptimized unless -fno-strict-aliasing is used
>>
>> c:\tmp\fortran>gcc  -flto -DUSE_LONG_LONG main.c sub.f -lgfortran
>> <no warnings or notes>
>>
>> Bill Dunlap
>> TIBCO Software
>> wdunlap tibco.com
>>
>> On Mon, Jul 6, 2020 at 4:39 PM Pierre Lafaye de Micheaux
>> <lafaye using unsw.edu.au>  <mailto:lafaye using unsw.edu.au>  wrote:
>>> Hello Bill,
>>>
>>> Thank you for your insight.
>>>
>>> First, my impression, is that the problem comes from how I declare the type of the function itself (and not its parameters), since the first (and only warning they seen on the CRAN) message is:
>>>
>>> <quote>
>>> myzhpevx.cpp:13:16: warning: type of �zhpevx_� does not match original declaration [-Wlto-type-mismatch]
>>>             void F77_NAME(zhpevx)(char *jobz, char *range, char *uplo,
>>> </quote>
>>>
>>> What I did is the following:
>>>
>>> <quote>
>>> void F77_NAME(zhpevx)(char *jobz, char *range, char *uplo,
>>>        const int *n, Rcomplex *ap, const double *vl,
>>>        const double *vu, const int *il, const int *iu,
>>>        const double *abstol, int *m, double *w,
>>>        Rcomplex *z, const int *ldz, Rcomplex *work, double *rwork,
>>>        int *iwork, int *ifail, int *info,
>>>        FC_LEN_T jobz_len,  FC_LEN_T range_len,  FC_LEN_T uplo_len);
>>>
>>>   char cjobz[2];
>>>   strncpy(cjobz, jobz[0], 1);
>>>   cjobz[1] = '\0';
>>>   char crange[2];
>>>   strncpy(crange, range[0], 1);
>>>   crange[1] = '\0';
>>>   char cuplo[2];
>>>   strncpy(cuplo, uplo[0], 1);
>>>   cuplo[1] = '\0';
>>>
>>>   F77_CALL(zhpevx)(cjobz, crange, cuplo, &n[0], ap, &vl[0], &vu[0], &il[0], &iu[0], &abstol[0], &m[0],
>>>    w, z, &ldz[0], work, rwork, iwork, ifail, &info[0], strlen(cjobz), strlen(crange), strlen(cuplo));
>>> </quote>
>>>
>>> Do you see anything wrong with the above?
>>>
>>> Thank you
>>>
>>> Best
>>> Pierre
>>>
>>> ________________________________
>>> From: William Dunlap<wdunlap using tibco.com>  <mailto:wdunlap using tibco.com>
>>> Sent: Tuesday, 7 July 2020 08:36
>>> To: Pierre Lafaye de Micheaux<lafaye using unsw.edu.au>  <mailto:lafaye using unsw.edu.au>
>>> Cc: Ivan Krylov<krylov.r00t using gmail.com>  <mailto:krylov.r00t using gmail.com>;r-package-devel using r-project.org  <mailto:r-package-devel using r-project.org>  <r-package-devel using r-project.org>  <mailto:r-package-devel using r-project.org>
>>> Subject: Re: [R-pkg-devel] warning: type of �zhpevx_� does not match original declaration [-Wlto-type-mismatch]
>>>
>>> Have you tried what is recommended in
>>> https://gcc.gnu.org/onlinedocs/gfortran/Argument-passing-conventions.html
>>> ?
>>>
>>> <quote>
>>> For arguments of CHARACTER type, the character length is passed as a
>>> hidden argument at the end of the argument list. For deferred-length
>>> strings, the value is passed by reference, otherwise by value. The
>>> character length has the C type size_t (or INTEGER(kind=C_SIZE_T) in
>>> Fortran). Note that this is different to older versions of the GNU
>>> Fortran compiler, where the type of the hidden character length
>>> argument was a C int. In order to retain compatibility with older
>>> versions, one can e.g. for the following Fortran procedure
>>>
>>> subroutine fstrlen (s, a)
>>>     character(len=*) :: s
>>>     integer :: a
>>>     print*, len(s)
>>> end subroutine fstrlen
>>>
>>> define the corresponding C prototype as follows:
>>>
>>> #if __GNUC__ > 7
>>> typedef size_t fortran_charlen_t;
>>> #else
>>> typedef int fortran_charlen_t;
>>> #endif
>>>
>>> void fstrlen_ (char*, int*, fortran_charlen_t);
>>>
>>> In order to avoid such compiler-specific details, for new code it is
>>> instead recommended to use the ISO_C_BINDING feature.
>>>
>>> Note with C binding, CHARACTER(len=1) result variables are returned
>>> according to the platform ABI and no hidden length argument is used
>>> for dummy arguments; with VALUE, those variables are passed by value.
>>> </quote>
>>>
>>> Bill Dunlap
>>> TIBCO Software
>>> wdunlap tibco.com
>>>
>>> Bill Dunlap
>>> TIBCO Software
>>> wdunlap tibco.com
>>>
>>>
>>> On Mon, Jul 6, 2020 at 3:13 PM Pierre Lafaye de Micheaux
>>> <lafaye using unsw.edu.au>  <mailto:lafaye using unsw.edu.au>  wrote:
>>>> Dear Ivan,
>>>>
>>>> Thank you very much for your response.
>>>>
>>>> I do not have more information than the one I gave in my previous email. (And on top of that, the computer I was using with Debian SID, a recent version of gfortran and the last version of R-devel, just broke.)
>>>>
>>>> My problem is that the CRAN team won't accept to publish my package until this WARNING problem is solved. And because I am unable to observe the warning on my side (I could not with the desktop that just broke, and I still can't with my current laptop with Debian 10), I have no clue on how to suppress this warning.
>>>>
>>>> Thank you in advance for any other advice.
>>>>
>>>> Best regards,
>>>> Pierre
>>>> ________________________________
>>>> From: Ivan Krylov<krylov.r00t using gmail.com>  <mailto:krylov.r00t using gmail.com>
>>>> Sent: Tuesday, 7 July 2020 06:11
>>>> To: Pierre Lafaye de Micheaux<lafaye using unsw.edu.au>  <mailto:lafaye using unsw.edu.au>
>>>> Cc:r-package-devel using r-project.org  <mailto:r-package-devel using r-project.org>  <r-package-devel using r-project.org>  <mailto:r-package-devel using r-project.org>
>>>> Subject: Re: [R-pkg-devel] warning: type of �zhpevx_� does not match original declaration [-Wlto-type-mismatch]
>>>>
>>>> On Fri, 3 Jul 2020 00:15:27 +0000
>>>> Pierre Lafaye de Micheaux<lafaye using unsw.edu.au>  <mailto:lafaye using unsw.edu.au>  wrote:
>>>>
>>>>> Found the following significant warnings:
>>>>>     myzhpevx.cpp:13:23: warning: type of _zhpevx__ does not match
>>>>> original declaration [-Wlto-type-mismatch]
>>>> I managed to reproduce the warning on R-devel r78607 built with
>>>> --enable-lto using gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1):
>>>>
>>>> myzhpevx.cpp:13:16: warning: type of �zhpevx_� does not match original declaration [-Wlto-type-mismatch]
>>>>             void F77_NAME(zhpevx)(char *jobz, char *range, char *uplo,
>>>>                  ^
>>>> zhpevx.f:232:7: note: type mismatch in parameter 20
>>>>         SUBROUTINE zhpevx( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU,
>>>>         ^
>>>> zhpevx.f:232:7: note: type �int� should match type �size_t�
>>>> /usr/lib/gcc/x86_64-linux-gnu/6/include/stddef.h:216:23: note: the incompatible type is defined here
>>>>   typedef __SIZE_TYPE__ size_t;
>>>>                         ^
>>>> zhpevx.f:232:7: note: �zhpevx� was previously declared here
>>>>         SUBROUTINE zhpevx( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU,
>>>>         ^
>>>>
>>>> Do you have access to the notes produced by the compiler in addition
>>>> to the warnings? Do they spell the same difference?
>>>>
>>>> If yes, the warning is likely to be safe to ignore. m4/R.m4 notes that,
>>>> while gfortran < 8 uses int instead of size_t for hidden size arguments,
>>>> it doesn't make a practical difference.
>>>>
>>>> --
>>>> Best regards,
>>>> Ivan
>>>>
>>>>          [[alternative HTML version deleted]]
>>>>
>>>> ______________________________________________
>>>> R-package-devel using r-project.org  <mailto:R-package-devel using r-project.org>  mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>> 	[[alternative HTML version deleted]]
>>
>>
>> ______________________________________________
>> R-package-devel using r-project.org  <mailto:R-package-devel using r-project.org>  mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>
>


	[[alternative HTML version deleted]]



More information about the R-package-devel mailing list