0

I am trying to run C code converted with f2c and am running into an issue.

In my MainFile.C I have:

static char fmt_4[] = "This is a very long string...";

static cilist io___94 = { 0, 6, 0, fmt_4, 0 };

printf("io___94.cierr: -%d-\n",io___94.cierr);
printf("io___94.ciunit: -%d-\n",io___94.ciunit);
printf("io___94.ciend: -%d-\n",io___94.ciend);
printf("io___94.cifmt: -%s-\n",io___94.cifmt);
printf("io___94.cirec: -%d-\n",io___94.cirec);

printf("sizeof io___94.cierr: -%lu-\n",sizeof(io___94.cierr));
printf("sizeof io___94.ciunit: -%lu-\n",sizeof(io___94.ciunit));
printf("sizeof io___94.ciend: -%lu-\n",sizeof(io___94.ciend));
printf("sizeof io___94.cifmt: -%lu-\n",sizeof(io___94.cifmt));
printf("sizeof io___94.cirec: -%lu-\n",sizeof(io___94.cirec));

s_wsfe(&io___94);

Prints:

io___94.cierr: -0-
io___94.ciunit: -6-
io___94.ciend: -0-
io___94.cifmt: -This is a very long string...-
io___94.cirec: -0-

sizeof io___94.cierr: -4-
sizeof io___94.ciunit: -4-
sizeof io___94.ciend: -4-
sizeof io___94.cifmt: -8-
sizeof io___94.cirec: -4-

s_wsfe is defined in wsfe.C from libf2c (I did not write this):

int s_wsfe(cilist *a)   /*start*/
#endif
{   int n;
    printf("a->cierr: -%ld-\n",a->cierr);
    printf("ciunit: -%d-\n",a->ciunit);
    printf("ciend: -%ld-\n",a->ciend);
    printf("a->cifmt: -%s-\n",a->cifmt);
    printf("cirec: -%d-\n",a->cirec);

    printf("sizeof a->cierr: -%lu-\n",sizeof(a->cierr));
    printf("sizeof ciunit: -%lu-\n",sizeof(a->ciunit));
    printf("sizeof ciend: -%lu-\n",sizeof(a->ciend));
    printf("sizeof a->cifmt: -%lu-\n",sizeof(a->cifmt));
    printf("sizeof cirec: -%lu-\n",sizeof(a->cirec));

    if(!f__init) f_init();
    f__reading=0;
    f__sequential=1;
    f__formatted=1;
    f__external=1;
    if(n=c_sfe(a)) return(n);
    f__elist=a;
    f__hiwater = f__cursor=f__recpos=0;
    f__nonl = 0;
    f__scale=0;
    f__fmtbuf=a->cifmt;
    f__cf=f__curunit->ufd;
    if(pars_f(f__fmtbuf)<0) err(a->cierr,100,"startio"); //Crash here
    f__putn= x_putc;
    f__doed= w_ed;
    f__doned= w_ned;
    f__doend=xw_end;
    f__dorevert=xw_rev;
    f__donewrec=x_wSL;
    fmt_bg();
    f__cplus=0;
    f__cblank=f__curunit->ublnk;
    if(f__curunit->uwrt != 1 && f__nowwriting(f__curunit))
        err(a->cierr,errno,"write start");
    return(0);
}

The results of the print statements:

a->cierr: -25769803776-
ciunit: -0-
ciend: -4323035328-
a->cifmt: -(null)-
cirec: -1-

sizeof a->cierr: -8-
sizeof ciunit: -4-
sizeof ciend: -8-
sizeof a->cifmt: -8-
sizeof cirec: -4-

cilist is defined in f2c.h:

/*external read, write*/
typedef struct
{   flag cierr;
    ftnint ciunit;
    flag ciend;
    char *cifmt;
    ftnint cirec;
} cilist;

And the problem I am running in to is that at the line indicated inside of s_wsfe the program crashes because f__fmtbuf is null, and tracking back it is because a->cifmt is null. I am expecting the value of a->cifmt to be the value of fmt_4[] from MainFile.C but it appears somewhere along the way it is getting set to null. I am not understanding why the value is null. Can someone point me in the right direction?

ez4nick
  • 9,756
  • 12
  • 37
  • 69
  • Try stepping with gdb – ulix Sep 08 '22 at 16:38
  • What does `c_sfe` do? It seems like the only place where `a->cifmt` could change. – Barmar Sep 08 '22 at 16:43
  • You're seeing the correct output from `printf("a->cifmt: -%s-",a->cifmt);`, right? – Barmar Sep 08 '22 at 16:44
  • @Barmar `a->cifmt` is null when it is printed out there. – ez4nick Sep 08 '22 at 16:45
  • I don't see how that could be. You're clearly setting it to `fmt_4` when you initialize `io___94`. – Barmar Sep 08 '22 at 16:47
  • Is there anything between the initialization and function call that uses that structure? – Barmar Sep 08 '22 at 16:48
  • What do you see if you do `printf("%s\n", io___94.cifmt);` before the call? – Barmar Sep 08 '22 at 16:49
  • `printf("%s\n", io___94.cifmt);` prints: "This is a very long string...". So that seems to be working fine. I don't have anything else between the initialization and function call using the same structure. – ez4nick Sep 08 '22 at 16:53
  • Can you garantee that both files see identical declaration of your structs? Also, where is `f__fmtbuf`defined? – Gerhardh Sep 08 '22 at 17:24
  • Are you building `f2c` yourself? If so, from what source and how are you building it? And what is the output of `printf("a: %p\n", (void *) a);` and `printf( "&io___94: %p\n", (void *) &io___94 );`. Those better print the same value - and I suspect they won't. – Andrew Henle Sep 08 '22 at 17:42
  • If the addresses from comment above are the same you might go a bit further and print `offsetof` and `sizeof` of the members. If you use that struct type in 2 files you might get different `packed` settings, different definitions of the used types etc. Make sure both files are actually seeing the world through the same glasses. – Gerhardh Sep 08 '22 at 17:55
  • Yes I am building `f2c` myself. Downloaded it from https://netlib.org/f2c/ and on Windows I used `nmake` with the Visual Studio 2022 developer command prompt to build it. Also yes those print statements return the same address. I probably should also note that I built all of the `f2c` components on Windows and this is all running on a Mac within Xcode as an ios application. I tried building it on the Mac but was running into a whole set of other issues getting it to build with xocde command line tools. – ez4nick Sep 08 '22 at 18:17
  • Updated question with results of `sizeof`.. They are not all the same.. But `cifmt` is? – ez4nick Sep 08 '22 at 18:29
  • Size of `cifmt` doesn't matter if the struct members before it have different size. `flag` has different type in both files. You must compile with different macro definitions, target architecture or something else. – Gerhardh Sep 08 '22 at 18:37
  • Do you build both files shown in the question on same machine and link together or is there some dynamic linking or some libraries built with different makefile etc. involved? – Gerhardh Sep 08 '22 at 18:38
  • All of the files referenced in the question are all being built on the same computer (Mac) and linked together. All of the `f2c` components were built with a makefile, `MainFile.C` came from running `f2c` itself and I built `f2c` from a makefile on Windows. – ez4nick Sep 08 '22 at 18:50

0 Answers0