4

6.2.5

At various points within a translation unit an object type may be incomplete (lacking sufficient information to determine the size of objects of that type).

Also

6.2.5 19) The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.

And

6.5.3.4 The sizeof operator shall not be applied to an expression that has function type or an incomplete type,

But Visual Studio 2010 prints 0 for

printf("Size of void is %d\n",sizeof(void));

My question is 'What are incomplete types'?

struct temp
{
    int i;
    char ch;
    int j;
};

Is temp is incomplete here? If yes why it is incomplete(We know the size of temp)? Not getting clear idea of incomplete types. Any code snippet which explains this will be helpful.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
StackIT
  • 1,172
  • 2
  • 13
  • 25
  • 1
    Because Visual Studio uses VC++. Try compiling the same with g++. You will get a warning like this: "main.cpp:7:36: warning: invalid application of 'sizeof' to a void type [-Wpointer-arith]" – Vaibhav Desai Sep 11 '13 at 06:08
  • 2
    Your `struct temp` is not incomplete type. This is incomplete type: `struct temp;` – Alex F Sep 11 '13 at 06:11
  • Everything bar the c++ tag itself (title, standards extracts, code use) points to this being a C question, so I'm removing the C++ tag. – paxdiablo Sep 11 '13 at 06:25

3 Answers3

8

Your struct temp is incomplete right up until the point where the closing brace occurs:

struct temp
{
    int i;
    char ch;
    int j;
};// <-- here

The structure is declared (comes into existence) following the temp symbol but it's incomplete until the actual definition is finished. That's why you can have things like:

struct temp
{
    int i;
    char ch;
    struct temp *next; // can use pointers to incomplete types.
};

without getting syntax errors.

C makes a distinction between declaration (declaring that something exists) and definition (actually defining what it is).

Another incomplete type (declared but not yet defined) is:

struct temp;

This case is often used to provide opaque types in C where the type exists (so you can declare a pointer to it) but is not defined (so you can't figure out what's in there). The definition is usually limited to the code implementing it while the header used by clients has only the incomplete declaration.

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • What I feel is doing `typedef struct temp { int i; char ch;int j;}Temp;` I am able to get the size, but by mentioning `sizeof(temp)` I am unable to get the size. It means, `temp` is not a complete type. Is that so? – StackIT Sep 11 '13 at 06:17
  • 3
    @Patil, in C, you would use `sizeof(struct temp)`. C++ allows you to drop the `struct`, C does not. Both `struct temp` and `Temp` are complete types following the typedef. – paxdiablo Sep 11 '13 at 06:19
  • Where you will find all these kinda information? No text book explains like this... – StackIT Sep 11 '13 at 06:32
  • 4
    @Patil, textbooks are for people who want to use the language in a hurry, they don't tend to delve in to these sort of aspects. They're measured by their ability to get someone from non-programmer to adequate, not adequate to guru. To understand these aspects, you need to spend thirty years using the language, examining the dark corners of it, and getting burnt by it frequently :-) – paxdiablo Sep 11 '13 at 06:37
  • 1
    You want the book C: A REFERENCE MANUAL by Samuel Harbison and Guy Steele. It tells you all about C without being written in unreadable standard-ese. – librik Sep 11 '13 at 07:58
2

No, your struct temp example is certainly complete; Assuming int is 4 bytes, and char is 1, I can easily count 9 bytes in that struct (ignoring padding).

Another example of an incomplete type would be:

struct this_is_incomplete;

This tells the compiler, "hey, this struct exists, but you don't know what's in it yet". This is useful for information hiding, but when you need to pass a pointer to the type:

int some_function(struct this_is_incomplete* ptr);

The compiler can correctly generate calls to this function, because it knows a pointer is 4 (or 8) bytes, even though it doesn't know how big the thing is that the pointer points to.

Jim Balter
  • 16,163
  • 3
  • 43
  • 66
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • But we need to mention `struct temp` in `sizeof` operator. – StackIT Sep 11 '13 at 06:12
  • What I feel is doing `typedef struct temp { int i; char ch;int j;}Temp;` I am able to get the size, but by mentioning `sizeof(temp)` I am unable to get the size. It means, `temp` is not a complete type. Is that so? – StackIT Sep 11 '13 at 06:12
  • `sizeof(temp)` means nothing in your context, because `temp` isn't a thing. `temp` != `struct temp` (unless you `typedef` it.) `sizeof(struct temp)` will give you the size. – Jonathon Reinhart Sep 11 '13 at 06:17
  • Thanks @JimBalter, I totally missed that. – Jonathon Reinhart Sep 11 '13 at 06:34
1

A type can be incomplete when its name is declared but not its definition. This occurs when you forward-declare a type in a header file.

Say, record.h contains:

struct record_t;

void process_record(struct record_t *r);

And record.c contains:

struct record_t {
    int data;
};

If, in another module, say "usage.c" you do this:

#include "record.h"

const int rec_size = sizeof(struct record_t); // FAIL

The type record_t is incomplete inside the "usage.c" compilation unit, because it only knows the name record_t, and not what the type is made up of.

Anthony
  • 12,177
  • 9
  • 69
  • 105
  • As the question is tagged C and C++, it might be worth mentioning that your examples are C++. – alk Sep 11 '13 at 06:21