views:

1874

answers:

6

This has happened before to me, but I can't remember how I fixed it.

I can't compile some programs here on a new Ubuntu install... Something is awry with my headers.

I have tried g++-4.1 and 4.3 to no avail.

g++ -g -frepo  -DIZ_LINUX -I/usr/include/linux -I/usr/include -I/include  -c qlisttest.cpp
/usr/include/libio.h:332: error: ‘size_t’ does not name a type
/usr/include/libio.h:336: error: ‘size_t’ was not declared in this scope
/usr/include/libio.h:364: error: ‘size_t’ has not been declared
/usr/include/libio.h:373: error: ‘size_t’ has not been declared
/usr/include/libio.h:493: error: ‘size_t’ does not name a type
/usr/include/stdio.h:294: error: ‘size_t’ has not been declared
...

the file...

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



@ubuntu:~/work/zpk/src$ cat /usr/include/linux/types.h | grep size_t
typedef __kernel_size_t    size_t;
typedef __kernel_ssize_t   ssize_t;

types.h is definitely in the path, and is getting picked up. I verified by changing the file name and get an error its missing...

Does anyone have any ideas...? I would really appreciate the help...

+2  A: 

It's hard to say what the issue is without seeing your complete source. The best way to debug issues like this is to use g++'s "-E" parameter to produce pre-processor output, and then look at that to figure out what's going on in your includes. Here's what the g++ info page says about "-E":

-E Stop after the preprocessing stage; do not run the compiler proper. The output is in the form of preprocessed source code, which is sent to the standard output.

Also, why not just include sys/types.h at the top of the file?

Addendum:

On my system, I've created a short file called foo.cc that contains only:

#include <time.h>

And then I've run:

g++ -E /tmp/foo.cc > /tmp/foo.pp

Looking at this output in much detail is very important. For example, I learned that /usr/include/bits/types.h has a typedef for __time_t, and that /usr/include/types.h then uses that typedef to say "typedef __time_t time_t". But, there are interesting other macros surrounding that definiton. Pay special attention to things like the macro "__BEGIN_NAMESPACE_STD" in /usr/include/time.h, which on my system seems to be an empty define. But, I can imagine that some other systems may have a different value for this macro, forcing the definition of time_t into some other namespace.

Read the Cpp info page, section "9 Preprocessor Output" that defines the format of the lines of the file. Of particular note is the section on:

Source file name and line number information is conveyed by lines of the form

# LINENUM FILENAME FLAGS

And then goes on to describe "FLAGS" which are of interest for this level of debugging.

slacy
thanks... I have tried adding sys/types.h and types.h to no avail. but -E is definitely useful - a grep on that for size_t and I can't find one typedef for it.... hmm
Sean
Another thing to try would be to compare the output of "gcc -E /tmp/foo.c" and "g++ -E /tmp/foo.cc" The former invokes the C compiler, and the latter the C++ compiler. (foo.c and foo.cc should have nothing but "#include <time.h>".
slacy
A: 

Generally, you shouldn't be using C .h files for C++. While you may find an easy way to get away with it, and while a lot of this was allowed in previous versions of g++ and in other compilers, the C++ standard defines size_t to be in cstddef (see section 18.2/table 17). g++ has been only getting more strict.

Remove all the includes paths you've added to your command (they are redundant), and add to the top of your source code if not included:

#include <cstddef>
using namespace std;
Samat Jain
This is not true. C headers are allowed in C++ translation units, and there's no need to even bother using C++ equivalents like cstddef.
Vladimir Prus
Please cite a reference on why you think the C++ equivalents are unnecessary. Are all these C++ compiler developers really just wasting their time?
Samat Jain
cstddef is just like stddef.h except that cstddef is in namespace std. The C++ equivalents are more convenient for avoiding namespace pollution, that's all.
David Thornley
Yes, C++ compiler developers are wasting their time. Given the amount of existing code that includes C headers, any compiler vendors that breaks the C headers will go out of business the morning after. So, the only "advantage" of <cxxx> is that they are in namespace std. The code example you gave has "using namespace std", so does not change anything. It's not apparent to me that "std" is advantage -- if your own code in in namespace, like it should be, you can use any names you like.
Vladimir Prus
+4  A: 

Start by removing -I/usr/include/linux and -I/usr/include. Adding system directories to include paths manually either has no effect, or breaks things. Also, remove -frepo for extra safety.

Vladimir Prus
+3  A: 

Have you installed the build-essential package?

sudo apt-get install build-essential
kalleh
Yes I had. but you definitely need this for sure. thanks.
Sean
+1  A: 

It should be in stddef.h or cstddef. types.h is not a standard library, and I believe it refers to types the OS needs.

David Thornley
+1  A: 

forgot to follow up on this: It turns out that /usr/include can not be included with /usr/include/linux on this particular distro. size_t seems to be get wiped out by the second includes.

My includes are now merely /usr/include and it works great.

-I/usr/include -I/usr/include/ace -I/usr/lib/glib-2.0/include -I/usr/include/glib-2.0...

Pulling out all the includes and playing with them fixed it. Thanks. Stackoverflow rocks.

Sean