Using !DEC$ ATTRIBUTES C, EXTERN directive for arrays

Using !DEC$ ATTRIBUTES C, EXTERN directive for arrays

Anthony E.的头像

All,

I am unable to get the code below to compile as a static library.  I declare the TEST variable as a C external real array (dimension 2).  No problem there, but, when I try to set the first element of TEST to 11.5, I get "Error: Conflicting attributes or multiple declaration of name.   [TEST]".  It's as if the compiler sees my assignment statement as a declration or it doesn't know that it's an array...what am I missing here?  Thanks much in advance!

      SUBROUTINE INITIAL_TEST_DATA()
      
      IMPLICIT NONE
      
      REAL TEST(2)
!DEC$ ATTRIBUTES C, EXTERN :: TEST
      
      TEST(1) = 11.5
      
      RETURN
      END

6 帖子 / 0 new
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项
Steve Lionel (Intel)的头像

It's what is extraneous, not missing.  Remove the C attribute which does not apply to variables.

But may I suggest the following, standard-conforming variation?

     MODULE MYVARS
     USE, INTRINSIC :: ISO_C_BINDING
     REAL(C_FLOAT), BIND(C) :: TEST(2)
     END MODULE MYVARS 
     SUBROUTINE INITIAL_TEST_DATA()
      USE MYVARS
      IMPLICIT NONE
      TEST(1) = 11.5
      
      RETURN
      END

Steve
Anthony E.的头像

Fair enough - I had arrived at a similar thought when reading about the ATTRIBUTES...however, I have not provided all the information about my situation. I'm attempting to align a C structure with a FORTRAN common AND get them to page-align in shared memory (using CreateFileMapping & MapViewOfFileEx).  An approach was using the compiler directive shown in my example above along with .asm files compiled with MASM to declare the variables as PUBLIC (with the appropriate C decorations).  So, as it turns out, you kind of can use !DEC$ ATTRIBUTES C, EXTERN for variabels even if that wasn't the intended use.  This approach actually works so long as the variables in the COMMON are not arrays.  Anyway, not important.  I'm now trying to scrap the directives & asm files to go with a more sane (and hopefully somewhat standard) approach at getting page-aligned COMMONs.  I should also mention that this is F77 code, so MODULE etc. are not available.  The sample code below works great for a single program, but when I create a second program and try to pass (void *)(int)(&shm__.var1) to MapViewOfFileEx() I get the following from GetLastError():

ERROR_MAPPED_ALIGNMENT1132 (0x46C)

The base address or the file offset specified does not have the proper alignment.

which I believe tells me that (the start of) my structure (or COMMON) is not aligned to a page boundary and i'm not sure how to force it to be using Visual Studio's linker.  Do you have any input on how to force page alignment of COMMONs?  thanks again for you input!  I may be able to attach some VS project files with src if it would help...

C PROGRAM:

#include <stdio.h>
#include <string.h>

extern struct {
   int    var1;
   double var2[2];
   short  var3;
   float  var4;
} shm__;

extern void app1(); // fotran subroutine

int main( int argc, char **argv )
{
   shm_init(0);
   
   app1();
   
   for (;;) {
      fprintf(stderr,"var = %d, var2[0] = %f, var2[1] = %f, var3 = %hd, var4 = %f\n",shm__.var1,shm__.var2[0],shm__.var2[1],shm__.var3,shm__.var4);
   }
   
   return (0);
}

FORTRAN SUBROUTINE:

      SUBROUTINE app1()
      
      IMPLICIT NONE
      
      integer          var1
      double precision var2(2)
      integer *2       var3
      real             var4
      
      common /shm__/
     * var1
     *,var2
     *,var3
     *,var4
      
      var1    = 10
      var2(1) = 8342.123
      var2(2) = 1234.5678
      var3    = 2
      var4    = 101.5
      
      RETURN
      END

Steve Lionel (Intel)的头像

You misunderstood.  You can use !DEC$ ATTRIBUTES EXTERN for variables. But not ATTRIBUTES C. If you simply replaced "C, EXTERN" with "EXTERN" in your original example it works fine.

Module variables with BIND(C) are interoperable with C extern structs, just like COMMONs.

We support !DEC$ ATTRIBUTES ALIGN:n :: varname

This requires a variable, not a common.

Steve
Steve Lionel (Intel)的头像

Oh, we have a different way of aligning commons:

!DEC$ PSECT /foo/ ALIGN=PAGE

Steve
Anthony E.的头像

Actually, I didn't misunderstand.  I saw what you were saying, and after reading about ATTRIBUTES in detail, I agree that the C part shouldn't be included....however, I was using that sytnax for variables and it was working.  Now I realize that, even though this worked, it was a kludge and not what ATTRIBUTE C was intended for.  To demonstrate my (mis)use/abuse of 'EXTERN, C' please take a look at my attached example.

I did not know '!DEC$ PSECT /foo/ ALIGN=PAGE' existed - that seems very promising...I will be looking into that approach today and will post back with results.  Thanks again!

附件: 

附件尺寸
下载 processexecgeneric.zip9.4 KB

登陆并发表评论。