r/C_Programming • u/International_Hat178 • 11h ago
Question Why not specifying what to include ?
Hi, sorry if there is English mistake, it's not my first language.
I found online that the #include is replaced by preprocessor by the whole file being included, and I wondered why C isn't made so we can specify only parts of the files to include (like `import { x, y, z } from "file"` in typescript) so the compiled file is lighter ?
9
u/SirCodedRed 10h ago
It’s also important to note that the final binary file only has the code you used and this is done by the linker.
8
u/SmokeMuch7356 8h ago
You're not importing code as such; you're just loading symbol and function declarations so that your code will compile.
For example, C requires functions to be declared before they can be used. IOW, if you write
int main( void )
{
printf( "Hello, world\n" );
}
and try to build it, the compiler will complain that printf hasn't been declared.1 There has to be a declaration of printf somewhere before it's called:
int printf( const char * restrict, ... );
int main( void )
{
printf( "Hello, world\n" );
}
stdio.h just contains the declarations for printf and scanf and other functions, not their actual implementations. It also contains typedefs for the FILE and fpos_t types, definitions for macros like NULL, etc.
- As of C99, anyway; for C89 and earlier it would just assume the function returned
int.
2
u/Zirias_FreeBSD 6h ago
This, at least as long as header files are used in the way they were intended to be used.
Might want to explicitly add what this means for
[...] so the compiled file is lighter ?
When used correctly, the contents of header files don't add anything to the compiled file, as they are only needed during compilation. Whether (and if so, how much) code is added by using stuff declared in headers depends entirely on linking.
3
u/sciencekm 10h ago edited 7h ago
You normally only have declarations in the files that you have in #include. The code still has to come from libraries or other C files. You only link the libraries and C object files that you need.
8
u/questron64 10h ago
When you say import in many languages it imports all the code you request at runtime, which is quite expensive if you want all the code from a large module. However, in C an #include is not import. Generally it's used to introduce header files which are intended to be declarations only, and it's not expensive to have all those declarations for most header files. All the functions those declarations refer to get compiled elsewhere at compile time, not a run time like in many scripting languages.
Some large libraries to help you out, though, and split up their header files into smaller chunks and allow you to include them individually, which does help large projects compile a bit quicker. But import and include are fundamentally different things, don't think of them as equivalent.
2
u/torsten_dev 10h ago
The preprocessor is not smart.
The compiler needs to read the entire file anyway.
import {x, y, z} wouldn't make your binary smaller than Dead code elimination.
All the globals and functions without static will still need unique names for the linker. C doesn't mangle names, and it doesn't have namespaces.
import {x,y,z} only benefit I could see in C is telling you why you includes the header.
3
1
u/mcsuper5 5h ago
If you only need one or two simple functions, you can just include the prototype before it is called instead of including the header. I'm saying it can work for some functions. No guarantees it is safe even if it works. Standard headers may just indicate prototypes for some functions, but may define some macros usually used when calling the code
These days, loading several hundred lines that usually don't even need to be compiled isn't a big deal.
Since gcc allows you to tell it the code has already been preprocessed. (see "-fpreprocessed" in the gcc manual) (*.i files are treated as mostly preprocessed c.) You could use another method of preprocessing the code. I don't know how standard that is.
You can also call the preprocessor separately. man cpp.
You could use a custom preprocessor, but you'd probably need custom headers and want to automate the preprocessing. (If you do something like this, INCLUDE an explanation in your source of the tool chain and any/all needed files for the tool chain. Nothing like going back to project 15 years later and not remembering how it worked. Been there and done that!)
1
u/Liam_Mercier 10h ago
Historical reasons, complexity of adding module style imports, etc.
There is a system like this in C++ but that is an entirely different language. There is also a lot more of a benefit to reducing compilation times in a language like C++ where you have a lot of instantiations and abstractions, versus a language like C which generally has better compile times.
1
u/torsten_dev 10h ago
c++ modules exist, but I've only heard disgruntled rumblings about it from c++ folk though.
0
u/ComradeGibbon 7h ago
Well now wouldn't that be nice.
There isn't any reason that couldn't be added to the language except the C++ standards committee would have a melt down.
-10
u/kinchkun 10h ago
Because c is a boomer language and doesn't have a module system
5
u/vertigosol 10h ago
Only runs on like 90% of embedded devices worldwide
1
u/Devatator_ 3h ago
Uh isn't that C++? My Arduino Uno and ESP32 both use C++ and looking around a bit ago it seemed like C++ was far more common for anything embedded
-6
u/kinchkun 10h ago
and?
2
u/vertigosol 9h ago
Shitty resource heavy languages are terrible for real programming on real devices. There is a reason c is still used
0
u/kinchkun 9h ago
A module system doesn't make language resource heavy. But compiling the same headers over and over again does make the compilation slower
1
u/Maqi-X 7h ago
No, it isn't. C complication model allows more parallel compilation than many languages with module systems do (for example, rust). In rust you need to split your project into separate crates because modules cannot be compilated simultaneously for whatever reason. Unlike C++, C headers are lightweight and they don't slow down compilation, and if they do you're using them wrong. C has one of the fastest compile times anyway because of how simple language it is.
6
45
u/pfp-disciple 10h ago
C is much older, and its design is much more straightforward. The behavior you're describing could be crudely done with macros at compile time. See
#ifdef.Modern linkers (and probably not so modern ones) will eliminate unused code, anyway. So, if a file is included that has functions a(), b(), c,(), and d() but only b() and d() are used, the final executable won't have the code for a() and c().