I'd like to look up all the functions, constants and types defined in C libraries: stdlib.h, stdio.h, ctype.h etc. So, when in C program I do: #include <stdlib.h> or #include <stdio.h> I'd like to know what are all the functions, constants and types I get with that?
What's the easiest way to do this locally on the computer? I'm not so much interested in online references, especially if they're not official.
Is there a manpage that lists this for eg stdlib? Does maybe GNU info program have docs for this? Or do I have to find an actual header file and look it up?
I'd prefer an universal approach, but if it differs from system to system I'm curious how to do that on both Mac and Linux?
When you include one of the standard C headers, at least three types of identifiers may be declared:
Identifiers specified by the C standard. The authoritative source for information on these is the C standard, plus documentation for the C implementation you are using.
Identifiers for extensions to the C language. For example, the headers may declare identifiers for POSIX functions. The headers might declare such identifiers only if you have requested them by defining certain preprocessor symbols before including the headers.
Identifiers for internal use of the C implementation. These identifiers commonly begin with an underscore followed by another underscore or a caputal letter, as the C standard reserves those. You can discover these identifiers by examining the actual header files in your C implementation, but you should not use them unless documentation for your implementation offers them for use.
Overall, if you want to know what C provides in the standard headers, you should read either the C standard (for authoritative information) or a good C textbook (for tutorial information). If you want to know what else is in the headers, there is a large variety of things that an implementation could put into the headers, so the way to find out what is there is to read the documentation for the implementation and/or to examine the header file and then find the documentation for the extra things it provides, such as the POSIX documentation.
You asked for sources on your computer. Your C implementation may come with documentation, and Unix includes documentation accessible via the man command. While you can examine the actual header files, it is important to understand the current contents of the headers do not constitute any promise about future behavior. Any internal identifiers may change in future versions, and the behavior of standard identifiers may change as permitted by the C standard.
Your terminology stdlib is not well-defined. There's a "Standard I/O Library" as part of the C Programming Language, and a stdlib.h header file.
For C identifiers, here's an overview for ISO C and POSIX identifiers.
Apart from that, you can look at the symbols in library files with
nm -AP /path/to/libfoobar.a
Update
To inspect a header in the form the compiler sees it, look at the result of preprocessing (-E):
$ gcc -E /usr/include/stdlib.h|less
typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
typedef unsigned long int __u_long;
[...]
typedef struct
{
int quot;
int rem;
} div_t;
typedef struct
{
long int quot;
long int rem;
} ldiv_t;
[...]
extern long int random (void) __attribute__ ((__nothrow__ , __leaf__));
[...]
Related
For example, here is a "hello, world" program without stdio.h included:
int puts(const char *str);
int main(void)
{
puts("hello, world");
}
I even think this can be a good programming style when my program gets longer and longer, for all functions called are listed at the beginning explicitly.
So my question is: Besides providing prototypes for standard library functions, what else does #include <stdio.h> do?
The (non-normative) Appendix J.2 of the C11 standard draft lists the following among examples of undefined behaviour:
— A function, object, type, or macro that is specified as being declared or defined by some standard header is used before any header that declares or defines it is included (7.1.2)
However, as pointed out by Keith Thompson, the 7.1.4p2 says:
2 Provided that a library function can be declared without reference to any type defined in a header, it is also permissible to declare the function and use it without including its associated header.
Thus using puts without including <stdio.h> can indeed be done in standard-conforming manner. However, you cannot declare fputs, since it requires a pointer-to-FILE as an argument, which you cannot do in a strictly conforming manner.
In addition, puts might also be a macro in presence of <stdio.h> and expand to something faster in the presence of the header.
All in all, the number of functions that can be declared properly without including headers is not that large. As for the functions that use some types from the headers - if you're asking with language-lawyer tag about C, the answer comes from the standard and the standard is rather outspoken about this: don't do it, or your program will not be strictly conforming, period.
<stdio.h> defines the type FILE, among other things. You can't portably call any function that takes a FILE* parameter or returns a FILE* result without #include <stdio.h>.
And there's really no good reason to declare any of the functions yourself rather than including the header.
When using proper program design, all prototypes of public functions are placed in header files and all function definitions are placed in c files. This is how you write C programs, period.
It is the industry de facto standard way of C programming and no professionals use any other design.
Your personal preference is not relevant here, nor are any loop-holes in the C standard that would allow you to make a different design. You should write your C programs in the same way as the rest of the world does.
Is it legal to forward declare structs and functions provided by the C standard library?
My background is C++ in which the answer is no. The primary reason for this is that a struct or class mandated by the C++ standard library can be a template behind the scenes and may have "secret" template parameters and so cannot be properly declared with a naive non-template declaration. Even if a user does figure out exactly how to forward declare a particular entity in a particular version of a particular implementation, the implementation is not obliged to not break that declaration in future versions.
I don't have a copy of any C standard at hand but obviously there are no templates in C.
So is it legal to forward declare entities in the C standard library?
Another reason that entities in the C++ standard library may not be forward declared is that headers provided by the implementation need not follow the normal rules. For example, in a recent question I asked if a C++ header provided by the implementation need be an actual file and the answer was no. I don't know if any of that applies to C.
The C standard library is used by both C and C++ but for this question I'm only asking about C.
Forward declarations of structs are always permissible in C. However, not very many types can be used this way. For example, you can't use a forward declaration for FILE simply because the tag name of the struct is not specified (and theoretically, it may not be a struct at all).
Section 7.1.4 paragraph 2 of n1570 gives you permission to do the same with functions:
Provided that a library function can be declared without reference to any type defined in a
header, it is also permissible to declare the function and use it without including its
associated header.
This used to be rather common. I think the reasoning here is that hard drives are slow, and fewer #include means faster compile times. But this isn't the 1980s any more, and we all have fast CPUs and fast hard drives, so a few #include aren't even noticed.
void *malloc(size_t);
void abort(void);
/* my code here */
yes you can this is perfectly valid.
this can be done with the standard library too.
double atof(const char *);
int main() {
double t = atof("13.37");
return 0;
}
#include <stdio.h>
Similiar things can be done with structs, variables etc.
I would recommend you read the wiki page which features some c examples:
http://en.wikipedia.org/wiki/Forward_declaration
this is specified in the c standard, Section 7.1.4 paragraph 2 of n1570
Provided that a library function can be declared without reference to any type defined in a header, it is also permissible to declare the function and use it without including its associated header.
For example, C11 dictates that size_t should be declared in the following header files:
stddef.h
stdio.h
stdlib.h
string.h
time.h
uchar.h
wchar.h
When reading C11, I found there are many other data types declared in more than one standard header files.
Questions
Let's say in the case of size_t. Why not just in stddef.h for simplicity?
Let's say a C compiler implements size_t in those header files. Are they guaranteed to have the same definition in those header files?
As an example of a function declared in stdio.h that requires size_t be predeclared, consider snprintf(). As it is, if you want to use it in your code, all you need to do is #include <stdio.h>. If size_t were declared only in stddef.h, you would have to
#include <stddef.h>
#include <stdio.h>
Not only that, but since stdio.h declares snprintf whether you use it or not, you would have to include both files every time you needed anything in stdio.h to avoid compiler errors; stdio.h would have an artificial dependency on stddef.h. That causes your source code to become longer and more brittle (notice that if you reverse the order of the two directives it would also break). Instead, we write header files so that they stand alone and do not depend on other headers, and this is what the C standardization committee decided on for the standard library.
Let's say in case of size_t. Why not just in stddef.h for simplicity?
The type is used in the declaration of functions in all those files. If it wasn't declared in <stdio.h> you would get a compilation error unless you first include <stddef.h>.
Let's say a C compiler implements size_t in those header files. Are they guaranteed to have the same definition in those header files?
Yes, they will have the same definition. Usually, the value is defined in a single place in a separate include file that is included by the others.
In some cases it may be possible to modify the definition with compiler options or defines, for example a compiler that allows 32/64 bit compilation may define size_t as a 32 or 64 bit unsigned entity depending on the target defined on the compiler command line.
There's a subtle difference between by and in - an implementation is completely free to define size_t in a single header, as long as it's defined when the specified headers are included. So, you have two options for that:
Define size_t in every single one and wrap each one in include guards
Define it in a single file, and wrap it in include guards
And yes, size_t must be defined as specified, which is (glibc):
typedef unsigned long size_t;
or
typedef unsigned int size_t
They don't say you have to be sane, they just say it needs to be defined at the time anyone includes one of those headers, because they depend on it being defined and can be used independently. Put simply, if you define something dependent upon size_t, then size_t must first (previously) be defined.
How (or rather, where) you do it is up to your implementation.
First of all, when one does a #include <stdio.h> there is no requirement that there actually exist a file anywhere called stdio.h, or that the compiler do anything with such a file. Rather, the requirement is that such a line must cause all identifiers which are specified as being associated with <stdio.h> to be defined according to specification. It would be perfectly legitimate for a compiler that saw #include <stdio.h> simply enable the use of certain identifiers that were hard-wired into the compiler. Because the easiest way for compiler vendors to make things behave as the spec requires is to have #include <stdio.h> directives run the text of some file stdio.h through the preprocessor, that's what many compilers do, but that's not required.
When the spec lists "files" where size_t should be declared, what it's really saying is that an #include directive that names any one of those files should create that identifier in global scope. That could be done by having files with all the listed names incorporate a definition of size_t, or by having size_t be built into the compiler but only enabling the built-in definition of the compiler sees a #include directive with one of the indicated names.
ML_EXTERN _ML_AB ML_FUNC(M_Process)
#ifdef ML_ARGS_LIST
(
ML_INT i
);
#endif
If I am creating interfaces for vendors (who need to implement those interfaces) why would I have the above declaration in my API? I think it's called a macro - why wouldn't I just declare the function like "normal": int M_Process();? What is the difference and what do the various parts of the declaration above do?
Macros like these are largely added for compatibility with different C compilers. You'll find this in code from the 1980s and 1990s for compilers that were either K&R compliant (predated ANSI C), or lacked various features.
You'd have to read the macro definitions to be absolutely sure, but there are some common patterns with this kind of thing. The macros break into a few types:
Linkage conventions
By defining ML_EXTERN, the API can support different calling conventions (e.g., stdcall, fastcall, etc.), or different kinds of external linkage (e.g., Microsoft's dllexport). This provides compiler compatibility and cross-platform compatibility while not substantially affecting code readability.
Consistent type sizes
The number of bits in types like int, short, and long are platform-dependent, although there are some restrictions. Many libraries that predate the standard inttypes.h and stdint.h headers use macros or typedefs to ensure that their types will be the same size on all platforms. ML_INT is either a macro or a typedef to an appropriately-sized integer type.
Prototype support
Many compilers in the 80s were built to the K&R standard for C and do not support ANSI function prototypes. The ML_FUNC and ML_ARGS_LIST macros address this.
If prototypes are supported, then ML_ARGS_LIST will be defined and ML_FUNC(x) would expand to x. The full expansion, ignoring the ML_EXTERN and _ML_AB would be:
M_Process(ML_INT i)
If the compiler does not support prototypes, then ML_FUNC(x) will expand to x() and the prototype argument list will be ommited. The full expansion would be:
M_Process()
In K&R C, all arguments are coerced according to the rules, and parameter variables are defined where the function is defined, not declared. See Wikipedia's entry on C for some details of the differences in C versions.
I found this line in stdio.h :
extern struct _IO_FILE *stdin;
Based on this 'extern' keyword, i assume this is just a declaration. I wonder where is stdin defined and initialized?
It's defined in the source code of your C library. You typically only need the headers for compilation, but you can find the source code for many open-source standard libraries (like glibc).
In glibc, it's defined in libio/stdio.c as like this:
_IO_FILE *stdin = (FILE *) &_IO_2_1_stdin_;
Which is in turn defined using a macro in libio/stdfiles.c like this:
DEF_STDFILE(_IO_2_1_stdin_, 0, 0, _IO_NO_WRITES);
The definition of the DEF_STDFILE macro varies depending on a few things, but it more or less sets up an appropriate FILE struct using the file descriptor 0 (which is standard input on Unix).
The definition may (and of course does) vary depending on your C library, and certainly by platform. If you want, you can continue the goose chase around the various parts of your standard library's I/O component.
The C standard explicitly states that stdin is a macro defined in stdio.h. It is not allowed to be defined anywhere else.
C11 7.21.1
"The header <stdio.h> defines several macros, ..." /--/
"The macros are..." /--/
stderr
stdin
stdout
which are expressions of type ‘‘pointer to FILE’’ that point to the FILE objects
associated, respectively, with the standard error, input, and output streams.
This macro can of course point at implementation details that are implemented elsewhere, such as in a "stdio.c" or whatever the compiler library chose to put it.
I believe it's defined in stdio.c which is compiled into in libc (on gnu based systems)
The definition will be implementation dependent, as will where you find it. For me, on OSX 10.6, it's defined in stdio.h, as a FILE (a struct).
stdin is of the type _IO_FILE, a struct which is clearly defined somewhere, probably in stdio.h. If not, check in the header files included in stdio.h for a definition of _IO_FILE.
In the standard library code, where else? In a Linux machine around here it's in libc.a:stdio.o, found using nm -o /usr/lib/libc.a | grep stdin | grep D. If you want to read some code, see the GNU C Library.