c - how to get access to FILE * instance?

I was curious about the object which fopen() returns.

So I made this little test program:
1
2
3
4
5
6
7
8
9
#include <stdio.h>

int main( void )
{
    FILE * file = fopen( "knapsack.dat", "r" );
    printf( "%llu, %llu\n", (long long unsigned) file, (long long unsigned) (*file) );
    fclose( file );
    return 0;
}

But it doesn't compile, instead I get this compiler error:
1
2
3
error: aggregate value used where an integer was expected
    6 |     printf( "%llu, %llu\n", (long long unsigned) file, (long long unsigned) (*file) );
      |                                                                           ^~~~~~

So what's wrong with, and how to fix that?
Last edited on
A FILE is a type of structure typedef as FILE. It is considered as opaque data type as its implementation is hidden. We don’t know what constitutes the type, we only use pointer to the type and library knows the internal of the type and can use the data.
https://www.geeksforgeeks.org/data-type-file-c/
What means that, that FILE is an opaque data type? The pointer needs to point to some data, and hence that data should been able to accessed, at least read. Isn't it?
Last edited on
"Opaque" in this case means that you as the user of the FILE pointer should not know what specific properties a FILE object has. The only purpose of the FILE pointer that you have is that it can eventually be passed to other library functions that expect a FILE pointer as a parameter.

There's nothing that says a FILE object should be convertible to a long long unsigned int, so don't attempt to do that.
Last edited on
So how could I read out the thing to what FILE* points?
Last edited on
So how could I read out the thing to what FILE* points?
You don't.

I have dealt with code that has attempted to use the internals of a FILE object as a shortcut. Guess what? The code broke when upgrading the compiler to the next version. Don't rely on any internal implementation of FILE.

___________________________________

Instead of going down this XY problem rabbit hole, please tell us what you're actually trying to accomplish.
Last edited on
It's nothing special problem that I try to solve. I wrote a knapsack problem solution with help of dynamic programming technique. The tutorial on solving that problem was written in C. So, just for getting a little bit experience with dealing of C based code I considered writing that stuff in C. If this someone interest, here the knapsack program, together with its input file:

knapsack.dat:
30 10
5 8
5 8
6 6
8 5
10 10
11 5
12 10
15 17
15 20
30 20


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/* knapsack problem solution with dynamically programming */

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

#define max_N 300 /* max items */
#define max_V 1000 /* max knapsack volume */
#define max_V1 1001
#define result_length (max_V1 * sizeof( int ))

int V; /* knapsack volume */
int n; /* count of items */
int v[max_N]; /* volume of each item */
int w[max_N]; /* value of each item */
int results[max_N][max_V1]; /* memorized solutions from previous calculations */

int knapsack( const int curr_vol, const int i )
{
    if( i < n )
    {
        /* test, if value was still calculated */
        if( results[i][curr_vol] != -1 )
            return results[i][curr_vol];

        /* calc value without item */
        int without_item = knapsack( curr_vol, i + 1 );
        /* calc value with item */
        int with_item = 0;
        if( curr_vol - v[i] >= 0 ) /* if item fits into knapsack */
            with_item = w[i] + knapsack( curr_vol - v[i], i + 1 );
        /* return max( with_item, without_item ) */
        return without_item >= with_item ?  without_item : with_item;
    }
    return 0;
}

int main( void )
{
    FILE * ifile = fopen("knapsack.dat", "r");
    fscanf( ifile, "%d %d", &V, &n);
    for( int i = 0; i < n; ++i )
        fscanf( ifile, "%d %d", &v[i], &w[i] );
    fclose( ifile );
    for( int i = 0; i < n; i++ )
        memset( results[i], -1, result_length );
    printf( "%d\n", knapsack( V, 0 ) );
    return 0;
}


I was still curious about what data fopen() returns, nothing special meaning, just for testing, what data the plain c-casts could convert.
Last edited on
Okay, I understand now. Sorry if I seemed terse, it's just that a lot of people will try do to funny things to try to solve a problem and get buried by the details.
Last edited on
Back to my origin problem. There was a misunderstanding how casts work. I thought, if I cast a struct, that in this case automatically the first date member will get selected, because of the member's alignment of the struct. This seems not to be the case. But accessing the data members of the FILE struct works.
1
2
3
4
5
6
7
#include <stdio.h>

int main( void )
{
    FILE * file = fopen("file.txt", "w");
    printf( "%#llx,\n", (long long) (file->._flags) );
}
Well apparently I didn't get my point across. You are not supposed to use the internal implementation of FILE. That stuff is what makes your code break when you go to a different compiler or even a different version of the same compiler.
I'm with you, @Ganado. When I code for something serious, or in general, I try to stick with the highest level of abstraction. I try to code platform-independent.
You can indeed read out what FILE* (a typedef for a struct) is made up of. The following shows how to do it for some of the simple data members that aren't even further structs).

A couple of points though:
1. It's great to know from a curiosity point of view, but who knows or really cares what/how the values are arrived at.
2. Given that, try setting a few values by all means, but unless you know what they mean you are on the road to a crashing waste of time.
3. The values are determined by the operating system running on a specific machine so there's quite a challenge if you want to second guess that. Even 2 of the same machine and OS will likely give you different answers.
4. As already said leave it to the higher level stuff.
5. Interesting though.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<iostream>
#include <cstdio>

int main ()
{
    FILE* pFile = new FILE;
    pFile = fopen ("myfile.txt","w");
    
    std::cout
    << "  _flags: " << pFile->_flags << '\n'
    << "_blksize: " << pFile->_blksize << '\n'
    << "   _file: " << pFile->_file << '\n';
    return 0;
}


Among many: https://code.woboq.org/userspace/glibc/libio/bits/types/struct_FILE.h.html#_IO_FILE
Last edited on
Topic archived. No new replies allowed.