2

I found the following code at lines 153-154 in the libelf.h of the libelf library:

/* Descriptor for the ELF file.  */
typedef struct Elf Elf;

I was looking for a struct definition of Elf but did not find it.

Later in the code, Elf is used, e.g.

/* Return descriptor for ELF file to work according to CMD.  */
extern Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref);

In the thread Why should we typedef a struct so often in C?, user "unwind" says:

Also note that while your example (and mine) omitted naming the struct itself, actually naming it is also useful for when you want to provide an > opaque type. Then you'd have code like this in the header, for instance:

typedef struct Point Point;

Point * point_new(int x, int y);

and then provide the struct declaration in the implementation file.

Yet, I couldnt find a definition of the struct Elf in any c file either.

What am I missing? What is the purpose of a typedef struct Name_xy Name_xy; without struct definition? Or is this impossible and I just did not find the struct definition?


Edit:

First, thank you for the numerous great replies. As my question was two-fold (at least), there are two answers:

  1. I did not find the definition because I did not have the lib/private.h file (thanks @molbdnilo to point out that the definition is in there). I installed the sources of elfutils and not of libelf. It seems that the private.h is not included in the elfutils source package.
  2. The answers from @Acrasidae, @sfjac, and @Matt McNabb explain the conceptual background (opaque type, encapsulation, minimising dependencies ...).
Community
  • 1
  • 1
langlauf.io
  • 3,009
  • 2
  • 28
  • 45
  • Maybe it's defined in another header file you haven't checked? – Some programmer dude May 08 '15 at 11:56
  • `typedef struct X X` is just a convention to prevent writing `struct` before each usage in C and I think the definition is somewhere for sure. – Emadpres May 08 '15 at 11:56
  • 1
    Perhaps the library is a pre-compiled one without source files? – Eugene Sh. May 08 '15 at 11:58
  • @EugeneSh. : I did an `apt-get source` to get the source files. And there are a lot of `.c` files in the folder... – langlauf.io May 08 '15 at 12:01
  • Btw, I clarified the part that you quoted in the linked-to answer, and edited the quote here so it still matches. – unwind May 08 '15 at 13:24
  • 1
    The definition should be in "private.h". – molbdnilo May 08 '15 at 13:39
  • The comment mentions returning a *descriptor* that word is often used as in 'file descriptor' when the caller is expected to treat the object as a an opaque 'handle' without directly accessing its structure. You should find you can accomplish everything the library offers without ever knowing how `Elf` is structured. – Persixty May 08 '15 at 13:54
  • @Allen : unfortunately I am afraid I do. I want to use the library from Python and e.g. ctypes requires a type, or at least a size – langlauf.io May 08 '15 at 14:53
  • @molbdnilo : thanks for your hint! This is it. It is the `private.h` in the lib folder. You could make an answer out of that so I can accept it. – langlauf.io May 08 '15 at 17:22

5 Answers5

4

In C++, struct Elf should be sufficient to declare the type, which is all that is necessary to return a pointer to that type. This is often done to hide implementation from users of the header file that will not use the Elf functionality themselves but may just pass on the pointer. Coding in this fashion on eliminates unnecessary dependencies on header files that aren't actually used. This approach to minimizing header dependencies can have a big impact on compile times in large C++ projects.

As others have mentioned, typedef struct Elf Elfis a C thing, allowing you to elide the struct in future declarations.

sfjac
  • 7,119
  • 5
  • 45
  • 69
3

typedef struct Elf Elf; is a short way of writing:

struct Elf;

typedef struct Elf Elf;

These lines do different things. The first one is usually called a forward declaration. It means that we can later have code such as:

// function prototype
struct Elf *elf_begin( stuff.... );

which prototypes a function that returns a pointer to struct Elf even though we do not actually know what is contained in the body of struct Elf. This is sometimes called opaque type and another instance of it is FILE * in the C standard library. There might be no definition of struct Elf anywhere.

The second part, typedef struct Elf Elf; is, as you say in your question, there to mainly avoid having to type struct all the time.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • You write "There might be no definition of struct Elf anywhere". I assume this could be the case here, since the `Elf` type is a "_Descriptor_ for the ELF file." From a practical point of view, it should be sufficient to have a struct definition of the Elf header. – langlauf.io May 08 '15 at 12:30
  • McNabb : I am unsure about your statement that there "might be no definition anywhere". See the answer and comments of @Acrasidae. Could you bring some details about your statement? – langlauf.io May 08 '15 at 18:44
  • 2
    @stackoverflowwww the library developer might have had a definition that was used in compiling the library, but if you are only using the library header plus the compiled binary for the library then the definition will not exist for you – M.M May 08 '15 at 22:45
1

Is it defined in decl.h?

For example:

http://www.opensource.apple.com/source/dtrace/dtrace-96/head/libelf.h http://www.opensource.apple.com/source/dtrace/dtrace-118/libelf/decl.h

jarmod
  • 71,565
  • 16
  • 115
  • 122
0

The possible explanation of this could be your project has some pre-compiled library files which contains definition of struct Elf.

Vagish
  • 2,520
  • 19
  • 32
  • I used `apt-get source`. How can I check if I have pre-compiled files? Say you are right, can get struct definitions from such precompiled files? – langlauf.io May 08 '15 at 12:05
0

What am I missing? What is the purpose of a typedef struct Name_xy Name_xy; without struct definition? Or is this impossible and I just did not find the struct definition?

In libelf.h, you have a declaration of an opaque type : Elf.

However, you do not find the definition of the Elf structure, and you are wondering why.

First of all, there is a definition somewhere, which looks like struct Elf{...};, however, you can not access to the definition because developers do not want you to access it. The only way you can use the contents of the Elf structure is because there is this declaration, typedef struct Elf Elf;, in libelf.h. By the way, struct Elf; is exactly the same, but with the typedef we know that there is more chance that the type is opaque.

A more illustrated example :

The header file :

/* libelf.h */
typedef struct Elf Elf;
extern Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref);
etc...

The implementation file :

/* libelf.c */
struct Elf {
  char * something;
  FILE * whatever;
};

Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref){
  /*doing something;*/
  /* ... */
}
etc...

This is exactly the principle of Encapsulation. The contents of this type are known and accessible only to the implementation of the API functions, clients (you) cannot directly access its contents. For developers, they have to compile a shared library, so you may find something like libelf.so somewhere (I do not know what the libelf do so I cannot help you on this). About the purpose of encapsulation, I advice you to read this.

I have nothing else in mind, but if you have more questions, do not hesitate.

Acrasidae
  • 71
  • 1
  • 7
  • You write: "First of all, there is a definition somewhere, which looks like struct Elf{...};". This contradicts to @Matt McNabb 's statement " There might be no definition of struct Elf anywhere." I am unsure what to think... – langlauf.io May 08 '15 at 12:59
  • Well I do think there is one definition... Otherwise, you could not even type "typedef struct Elf Elf" without a compile time error. Matt McNabb should bring some details about his statement. – Acrasidae May 08 '15 at 13:40
  • 1
    the existence of the struct definition in `lib/private.h` backs both your points: The struct definition exists, and it is not in the file for encapsulation reasons (_private_.h). – langlauf.io May 08 '15 at 18:41