Thread: Help using: typedef int64_t newtypedef[2]

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    22

    Help using: typedef int64_t newtypedef[2]

    Hi there,

    Please, could anyone tell me why I am not getting the expected result when running this code?


    Code:
    #import <Foundation/Foundation.h>  
      
    typedef int64_t msize_t[2];  
      
    int getMatrixSizeFromFile(const char *filePath, msize_t *matrixSize);  
      
    int getMatrixSizeFromFile(const char *filePath, msize_t *matrixSize)  
    {  
        FILE *fid;  
          
        fid=fopen(filePath,"r");  
          
        if (fid!=NULL)  
        {  
            float_t ffloat;  
            int64_t fchar;  
            int64_t counter[2]={-2,1};  
            fpos_t position[3];  
              
            position[1]=-1;  
            fgetpos(fid,&position[2]);  
              
            while (position[1]!=position[2])  
            {  
                counter[0]++;  
                  
                position[0]=position[1];  
                position[1]=position[2];  
                  
                fscanf(fid,"%f",&ffloat);  
                fgetpos(fid,&position[2]);  
            }  
              
            rewind(fid);  
              
            for (int64_t i=0; i<position[0]; i++) {  
                fchar=fgetc(fid);  
                  
                if (fchar=='\n') counter[1]++;  
            }  
              
            fclose(fid);  
              
            if (counter[0]%counter[1]==0) {  
                *matrixSize[0]=counter[1];  
                *matrixSize[1]=counter[0]/counter[1];  
                  
                printf("From Function => Matrix size: %lli x %lli.\n",*matrixSize[0],*matrixSize[1]);  
            } else {  
                printf("Error: File does not contain a matrix.\n");  
                return -2;  
            }  
              
        } else {  
            printf("Error: File could not be opened.\n");  
            return -1;  
        }  
          
        return 0;  
    }  
      
      
      
      
      
      
      
    int main (int argc, const char * argv[])  
    { 
            const char *filePath="/mymatrix.txt";  
              
            FILE *pFile=fopen(filePath,"w+");  
              
            for (int i=0; i<7; i++)  
            {  
                if (i>0) fputs("\n",pFile);  
                  
                for (int j=0; j<4; j++)  
                    fprintf(pFile,"%.5f ",3/8.*(float)i-5*(float)j);  
            }  
              
            fclose(pFile);  
              
            msize_t msize={0,0};  
              
            getMatrixSizeFromFile(filePath,&msize);  
              
            printf("From Main     => Matrix size: %lli x %lli.\n",msize[0],msize[1]);  
          
            return 0;  
    }


    In theory, the result should be:

    From Main => Matrix size: 7 x 4.

    when function main is evaluated, but instead I am getting:

    From Main => Matrix size: 7 x 0.

    Any idea?


    Thank you very much. Any help will be greatly appreciated.

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Try calling getMatrixSizeFromFile without the ampersand and remove the asterisks on all references to matrixSize.

    What's happening is that *matrixSize[1] is being interpreted as (int64_t[2]*)matrixSize + 1 (pointer arithmetic adding 16 bytes!).
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Code:
    $ make foo
    gcc -g -Wall -o foo foo.c -lpthread -lm
    foo.c:1:2: warning: #import is a deprecated GCC extension [-Wdeprecated]
    foo.c:1:36: fatal error: Foundation/Foundation.h: No such file or directory
    • I would use #include if you want to include a header. Not only is #import deprecated, GCC's website says it's poorly implemented: The C Preprocessor. Use include guards: Include guard - Wikipedia, the free encyclopedia
    • I don't have Foundation/Foundation.h, whatever that is, so I can't compile this.
    • You need to #include stdio.h for printf and stdint.h for int64_t.


    After doing that, here's what I get:
    Code:
    $ make foo
    gcc -g -Wall -std=c99 -o foo foo.c -lpthread -lm
    foo.c: In function ‘getMatrixSizeFromFile’:
    foo.c:16:9: error: unknown type name ‘float_t’
    foo.c:21:20: error: incompatible types when assigning to type ‘fpos_t’ from type ‘int’
    foo.c:24:27: error: invalid operands to binary != (have ‘fpos_t’ and ‘fpos_t’)
    foo.c:31:13: warning: format ‘%f’ expects argument of type ‘float *’, but argument 3 has type ‘int *’ [-Wformat]
    foo.c:37:28: error: invalid operands to binary < (have ‘int64_t’ and ‘fpos_t’)
    What is a float_t type? Maybe it's defined in the foundation stuff. I had to change it to a plain float type for it to work. Fixing that, however, still leaves the errors with fpos_t being incompatible with int and int64_t. From the fgetpos man page (emphasis mine):
    Quote Originally Posted by man fgetpos
    DESCRIPTION
    The fgetpos() and fsetpos() functions are alternate interfaces equivalent to ftell() and fseek() (with whence set to SEEK_SET), setting and storing the current value
    of the file offset into or from the object referenced by pos. On some non-UNIX systems an fpos_t object may be a complex object and these routines may be the only
    way to portably reposition a text stream.

    fpos_t isn't meant to be compared with and assigned to ints like that. Use ftell instead if you really need this sort of functionality.

    What is this code supposed to do exactly? It feels like it's way more complicated than it needs to be. Any reason a simple fgets/sscanf loop wont work?

    It's generally frowned upon to "hide" arrays (and pointers for that matter) in typedefs, unless you are building a totally opaque data structure for some library. I would just pass in a width and a height variable. Maybe make them size_t or unsigned types, since that's more appropriate. This is actually the root of your problem. Read this: C Language Operator Precedence Chart. Notice that the array index operator [ ] has higher precedence than unary * (for dereferencing a pointer).

    In your function, matrixSize is a pointer to an array of int64_t. Because of the precedence, you are effectively doing *(matrixSize[0]). That is, you're treating the pointer to the array as an array itself, and dereferencing the 0th/1st element of that. What you need is to dereference the pointer first, then take the 0th/1st index, e.g. (*matrixSize)[0].

    But all that is unnecessary anyhow. When you pass in an array, you really pass in a pointer to the first element, thus you can change the array elements in the function and have those changes persist when the function is done. Think of how strcpy works, you don't pass in &dest for the destination. Remove the * from msize_t *matrixSize in your prototype and function definition, remove the * from all the instances of matrixSize in the function and remove the & from msize in the call to getMatrixSizeFromFile.

  4. #4
    Registered User
    Join Date
    Mar 2012
    Posts
    22
    Quote Originally Posted by oogabooga View Post
    Try calling getMatrixSizeFromFile without the ampersand and remove the asterisks on all references to matrixSize.

    What's happening is that *matrixSize[1] is being interpreted as (int64_t[2]*)matrixSize + 1 (pointer arithmetic adding 16 bytes!).
    Thank you very much, oogabooga.

    Now the code is running as expected. But, with your explanation I have lost the notion of pointers.

  5. #5
    Registered User
    Join Date
    Mar 2012
    Posts
    22
    Dear anduril462, thank you very much for the clarification. Everything is clear now.

    P.S. Foundation.h is a header (aka the Foundation framework) available for Mac OS X systems only and int64_t is an alias for long long int

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by adarpodracir View Post
    P.S. Foundation.h is a header (aka the Foundation framework) available for Mac OS X systems only and int64_t is an alias for long long int
    That is true, but it's not C. It's an Objective-C framework which is why the #import directives are used, since Objective-C is a strict superset of C, all C code will compile as Objective-C. Not the other way around though, to compile this, I need to add: -framework Foundation -ObjC

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. typedef .....
    By roaan in forum C Programming
    Replies: 9
    Last Post: 07-24-2009, 01:14 PM
  2. typedef
    By George2 in forum C++ Programming
    Replies: 6
    Last Post: 02-19-2008, 06:29 AM
  3. typedef help
    By switchcase in forum C++ Programming
    Replies: 13
    Last Post: 10-05-2007, 12:21 PM
  4. Number too big for int64_t?
    By Doriän in forum C Programming
    Replies: 23
    Last Post: 09-02-2007, 04:53 PM
  5. typedef
    By linuxdude in forum C Programming
    Replies: 5
    Last Post: 11-21-2003, 05:41 PM