Why is stddef.h not in /usr/include? - c

I have compiled the gnu standard library and installed it in $GLIBC_INST.
Now, I try to compile a very simple programm (using only one #include : #include <stdio.h>):
gcc --nostdinc -I$GLIBC_INST/include foo.c
The compilation (preprocessor?) tells me, that it doesn't find stddef.h.
And indeed, there is none in $GLIBC_INST/include (nor is there one in /usr/include). However, I found a stddef.h in /usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include.
Why is that file not under /usr/include? I thought it belonged to the standard c library and should be installed in $GLIBC_INST/include.
How can I compile my foo.c with the newly installed standard library when it doesn't seem to come with a stddef.h?
Edit: Clarification
I feel that the title of this question is not optimal. As has been pointed out by some answers, there is not a requirement for stddef.h to be in /usr/include (or $GLIBC_INST/include, for that matter). I do understand that.
But I am wondering how I can proceed when I want to use $GLIBC_INST. It seems obvious to me (although I might be wrong here) that I need to invoke gcc with --nostdinc in order to not use the system installed header files.
This entails that I use -I$GLIB_INST/include. This is clear to me.
Yet, what remains unclear to me is: when I also add -I/usr/lib/gcc/x86..../include, how can I be sure that I do have in fact the newest header files for the freshly compiled glibc?

That's because files under /usr/include are common headers that provided by the C library, for example, glibc, while the files at /usr/lib/gcc are specific for that particular compiler. It is common that each compiler has their own different implementation of stddef.h, but they will use the same stdio.h when links to the installed C library.

When you say #include <stddef.h> it does not require that /usr/include/stddef.h exists as a file on disk at all. All that is required of an implementation is that #include <stddef.h> works, and that it gives you the features that header is meant to give you.
In your case, the implementation put some of its files in another search path. That's pretty typical.

Why is that file not under /usr/include?
Because there's absolutely no requirement for standard headers to be located at /usr/include/.
The implementation could place them anywhere. The only guarantee is
that when you do #include <stddef.h>, the compiler/preprocessor correctly locates and includes it. Since you disable that with -nostdinc option of gcc, you are on your own (to correctly give the location of that header).

Related

How does compiler link in libraries in your code?

So I'm going through CS50 introduction course.
And I'm confused about the fact that if you write in IDE #include some header file, which tells computer to find some library, and your compiler will find that code and combine it with your code.
But then how does compiler find that code? Like I just type in #include <cs50.h> for example. But how does it find that code when I don't have it on my PC? Why would I have it without finding it online and downloading it beforehand? Does it look online and then download file, which it uses now and in future for my programs when I call #include? And if so does it mean that you can't properly program without connection to internet?
And im confused about the fact that if you write in ide #include some header file which tells computer to find some library,
Be careful with terminology. #include tells the compiler to find some header. The word library in C usually refers to the file with compiled code (.a, .lib, .so, .dll).
and your compiler will find that code and combine it with your code.
This is right. By and large, the effect is the same as copying and pasting the contents of the header in the place of the #include statement.
But then how does compiler find that code? Like i just type in #include Cs50 for example.
The compiler has default search paths built in, where it looks for the header that is being #included. Typically directories like /usr/include and /usr/local/include are built into the compiler, as well as the current directory .. You can add more search paths through compiler command line arguments, for example -I/some/path in gcc and clang.
But how does it find that code when i dont have it on my pc
It doesn't. You will get an error like "Cs50: No such file or directory".
If this works on your university's system, probably the header is installed on that system in some central location.
why would i have it without finding it online and downloading it beforehand? Does it look online and then download file which it uses now and in future for my programs when i call #include?
It doesn't.
And if so does it mean that you cant properly program without connection to internet?
C was developed in the 1970s. The internet barely existed yet. You can program perfectly well in C without an internet connection – if you can do it without StackOverflow, of course ;)
The code of the library must be present on your computer or nothing will work. There's no such thing as magic downloads of libraries, C compilers and linkers have worked the same since long before the Internet was even invented.
Standard library headers are typically downloaded & installed along with the compiler. They are also very likely already pre-linked into some convenient format for the target system. You don't need to worry about manually adding standard libs to your project since the compiler will take care of that for you.
Custom headers require their corresponding .c files or linked libs to be present too, but they must be manually added to the current project. Either by adding them in your IDE's project, or as in the old days by creating a make file.
How that works in CS50 I don't know, but the lib obviously comes pre-installed somehow and they have hidden how to the students. We wouldn't want to risk CS50 students actually learning how programming works, now would we...
if you write in ide #include some header file which tells computer to find some library
Slight misunderstanding. When you type #include "somefile.h" into your program, the first stage of C and C++ compilation called the pre-processor will search for that file (called a "header") from the INCLUDE path. That is, the pre-processor will search through the local directory of the .c file, then a specified set of standard directories, and perhaps your own project directories to find a file called "somefile.h". The INCLUDE path is highly configurable with IDEs, command lines, and environment variables. Upon finding that file, the result is that the contents of that file are virtually substituted directly into your source code, exactly where the #include statement originally appeared. It's as if you had typed that exact file contents yourself into your .c file. After the textual substitution of the #include statements with the file contents, the intermediate file contents are handed off to the compiler stage to convert to object (assembly) code.
Like i just type in #include Cs50 for example. But how does it find that code when i dont have it on my pc
If the file can't be found, the pre-processor stage of the compile will fail and the whole thing comes to an end. I'm not sure what's in Cs50, but if you type #include "Cs50" and it works, then my guess is that your university environment has some project or environment configuration that adds a course specific include directory into your compilation path. Difficult to say since you didn't specify how you were building your code. Most IDEs will let you right-click on a #include statement and navigate to the actual source of the header file so you can inspect its contents and see where it originates from on your disk.
Also, your title says "linking", but you really mean "including". Linking is final stage after the compiler compiles all source files to object code to produce a final executable program.
.h files (should only) contain data type definitions, extern declarations, and function prototypes. .h files are not libraries.
So the compiler will know what parameters function take and what is the return type. The compiler will know how to call them. It will also know the type of variables defined somewhere else in the code (including the libraries). When the compiler compiles the code it generates intermediate files called object files.
Those files are later linked together by a special program called linker. This program will find the actual code of the functions in other object files or libraries (Libraries are basically sets of object files grouped in one larger file). It happens behind the scenes. If you need to tell the linker to use specific library you simply use command line option. For example to use math library you need to use -lm compiler command line option.
But how does it find that code when I don't have it on my PC?
The library file has to be present in your file system. Otherwise linker will not be able to link functions or variables from that library.
And if so does it mean that you can't properly program without
connection to internet?
No, it means that you have to have properly configured toolchain (ie all libraries needed present in your file system).
But then how does compiler find that code?
For your level of knowledge: some libraries are linked by default. Other not - so you need to tell the compiler/linker what you want to use.
--gcc & binututils related--
Linking is generally quite a complicated process and the compiler has its own configuration files called "spec files" and linker has "linker scripts". But explaining what those files do is rather an advanced topic far beyond the scope of this question.

How to work around compiler built-in types in C standard header files

I am working on a static analysis tool for C. I need to pass the code being analysed through the C preprocessor so that the tool can see the library function prototypes, type definitions, etc. Unfortunately both with clang on Mac OS X and gcc on Linux distros, some of the standard header files refer to compiler built-in types like __builtin_va_list that my tool doesn't know about. Does anyone have any suggestions for how to work around this. One possibility, if it's available somewhere, would be a vanilla-flavoured set of header files that produce C that conforms strictly to the standard. The header files don't have to map to any ABI, as the tool doesn't need to compile and run the code: they just have to give the API promised by the C standard. Any suggestions will be gratefully received.
Instead of finding a set of standard standard header files, you can just use a set of empty files with the expected names and pass the source code through the compiler preprocessor with a -Idirectory option. Your syntax analysis tool should be able to deal with the remaining symbols.
It would be useful to have a preprocessor option in addition to -dI to preserve #include lines instead of handling them.
In the mean time, you can try using the include files from my nolibc repository.

C - tcc finds error in commdlg.h?

I'm attempting to write a C program incorporating OPENFILENAME and of course I need the header file. So, following the instructions provided with tcc, I downloaded the header files MinGW uses for the Win32 API (and the library files) and put them in the appropriate directories as instructed. However, when I come to compile the program, I get the following error:
In file included from sw1.c:2:
c:/prg/tcc/include/winapi/commdlg.h:503: declaration list expected
This seems rather odd, given it's a standard header. So, I look up the line and it's typedef __AW(CHOOSECOLOR) CHOOSECOLOR,*LPCHOOSECOLOR;, which doesn't look very valid to me but then I'm not really a C expert and I've mainly been writing in Linux. I have no idea why it's going wrong though and no knowledge of how to fix it? Is it a bug in tcc?
As evidence that this should be possible, here is the appropriate passage from the tcc readme:
Header Files:
The system header files (except _mingw.h) are from the MinGW
distribution:
http://www.mingw.org/
From the windows headers, only a minimal set is included. If you need
more, get MinGW's "w32api" package.
I understand that this question is similar to Error when including Windows.h with TCC but my "windows.h" file does work - it's just this that doesn't.
Does anyone know how to solve this? I'm really at a loose end!

GCC linked library for compile

Why do we have to tell gcc which library to link against when that information is already in source file in form of #include?
For example, if I have a code which uses threads and has:
#include <pthread.h>
I still have to compile it with -pthread option in gcc:
gcc -pthread test.c
If I don't give -pthread option it will give errors finding thread function definitions.
I am using this version:
gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
This may be one of the most common things that trip up beginners to C.
In C there are two different steps to building a program, compilation and linking. For the purposes of your question, these steps connect your code to two different types of files, headers and libraries.
The #include <pthread.h> directive in your C code is handled by the compiler. The compiler (actually preprocessor) literally pastes in the contents of pthread.h into your code before turning your C file into an object file.
pthread.h is a header file, not a library. It contains a list of the functions that you can expect to find in the library, what arguments they take and what they return. A header can exist without a library and vice-versa. The header is a text file, often found in /usr/include on Unix-derived systems. You can open it just like any C file to read the contents.
The command line gcc -lpthread test.c does both compilation and linking. In the old days, you would first do something like cc test.c, then ld -lpthread test.o. As you can see, -lpthread is actually an option to the linker.
The linker does not know anything about text files like C code or headers. It only works with compiled object files and existing libraries. The -l flag tells it which libraries to look in to find the functions you are using.
The name of the header has nothing to do with the name of the library. Here it's really just by the accident. Most often there are many headers provided by the library.
Especially in C++ there is usually one header per class and the library usually provides classes implementations from the same namespace. In C the headers are organized that they contain some common subset of functions - math.h contains mathematical operations, stdio.h provides IO functions etc.
They are two separate things. .h files holds the declarations, sometimes the inline function also. As we all know, every functions should have an implementation/definition to work. These implementations are kept seperately. -lpthread, for example is the library which holds the implementation of the functions declared in headers in binary form.
Separating the implementation is what people want when you don't want to share your commercial code with others
So,
gcc -pthread test.c
tell gcc to look for definitions declared in pthread.h in the libpthread. -pthread is expanded to libpthread by linker automatically
there are/were compilers that you told it where the lib directory was and it simply scanned all the files hoping to find a match. then there are compilers that are the other extreme where you have to tell it everything to link in. the key here is include simply tells the compiler to look for some definitions or even simpler to include some external file into this file. this does not necessarily have any connection to a library or object, there are many includes that are not tied to such things and it is a bad assumption. next the linker is a different step and usually a different program from the compiler, so not only does the include not have a one to one relationship with an object or library, the linker is not the compiler.

How to know, what is inside a header file?

I wonder what is inside stdio.h and conio.h etc.
I want to know how printf and scanf are are defined.
Is there a way I can open stdio.h and see what is written inside?
Depending on your implementation, you should be able to open any .h file in your favorite editor and read it directly; they're (usually) just plain text files.
However, stdio.h will only give you the declarations for printf and scanf; it won't contain the source code for them. Most compilers don't ship the source code for standard library functions; instead, they ship precompiled libraries which are linked with your code when you build the executable.
If you're willing to spend some money, P.J Plauger's The Standard C Library is a good resource that shows an implementation of the standard library functions.
When the preprocessor includes a header file into a source file, that inclusion is very much literal. That means that the header files are normal text files with source in them, and must be readable by the compiler (and therefore by you). You just have to find where they are, and you can open them like any other text file.
However, you won't find out how functions are defined, just how they are declared. And some structures are supposed to be "black boxes", whose data members should be considered private. Usually the source for the standard C library is available or downloadable, so try and find that too. It all depends on what compiler you're using.
You might also want to check out a reference site such as this one. There you can find pretty detailed information about e.g. printf.
Those headers generally chain include more machine/OS specific headers.
If you are on Linux/OS X then you can get some more info with
man stdio
Also check out http://www.cplusplus.com/reference/cstdio/ https://en.wikipedia.org/wiki/Conio.h
Most compilers allow you to read the results after the preprocessor (the compilation step that processes the #include directives) has been run. With gcc for instance, use the -E command-line option.
You can always rely on the Internet's supply of Unix-style manual pages, by searching for "man something" you can look for the relevant manual section for something.
For instance, there are pages for both printf() and scanf().
You can easily see there that the declarations aren't very special, and quite obvious from the usage. It's just int printf(const char *format, ...); for instance.
the content of some headers is defined by the C-Standard.
other headers are defined by the library that provides it.
Some headers are defined from the system for that you are writing the code (may fall into the second case since the OS provides the libs)
depending on that you may look into c language reference or you may look into the libraries manual or in the OS's API reference.
But one thin is for sure. if you can include a header (and the compiler does not complain that he could not find it) than you also can look into it. just look into the standard include directories of the compiler or the additional include directories that are specified in project file ore Makefile to find the files on your file system.
But usually the better way is to look in the Documentation because the header itself may be difficult to read because of many #ifdefs and further includes
The most fundamental way to find out what's inside those headers is to read them. Of course, you must locate them first. To this end you can use this short shell code:
gcc -E -M - << EOF
#include <stdio.h>
EOF
This will provide you with a complete list of all the headers directly or indirectly included by #include <stdio.h>. Of course, if you are only interested in the 'stdio.h' header itself, you can just do
locate stdio.h
but this will usually list quite a few false positives.

Resources