Are header files strictly necessary when the code is open source? - linker

It was my understanding that header files were a developed practice, the header files created by copying all the externally-meaningful symbols from a source C file. Thus being able to give the linking information to a user and their compiler without giving them the source code.
Of course there is value in header files beyond the technical requirements of the compiler. This is outside the scope of my question. I am not asking for practical advice, that is to say, I'm not actively trying to link against a source c file, nor would I. I am trying to understand why it seems never to be done, under the impressions that there is no technical limitation (though there being a business limitation).
To phrase it a different way,
Could the complete source file be used for linking?
Technically speaking.

Related

Can i have multiple C source files in the same project (Visual Studio 19)?

Beginner here. I code in C atm. So Ive just started using VS 2019. A few troubles along the way but I got Build error along with LNK 2005 and LNK 1169. Turns out I cant have multiple files in the same project. Especially if Im using same header in the files. In this case it was stdio.h and math.h. I recreated this multiple times. The code would compile without a hitch only if one file was present in the project. Or atleast just one file with that particular header. Which pretty much prevents me from having multiple C source files under the same project. So is there any way to have multiple files in the same project without these errors.
A little annoying that I can't have multiple files with same header which is impossible cause obviously, I gotta use stdio.h everywhere. enter image description here
Essentially a Solution is a container used to contain multiple Projects, you can choose to compile either the whole Solution (so all the projects in the solution), or a single Project in said Solution.
Each Project can have only 1 main() because otherwise your OS won't know where to start executing, of course you can have multiple source files in the same project otherwise for even smaller projects you'd have a single file with a huge number of lines.
This structure is quite common in many IDEs (maybe with different names than Project and Solution, this is just a nomenclature that VS uses), it isn't really bound to Windows or Linux in particular.
Try on Linux to have multiple source files with multiple main() and try to compile then together with gcc, you'll see that you get a very similar error.
You also can't have the same function definition in multiple files otherwise you get the LNK 2005 linker error that you've seen. This is because when the Linker is linking your files if it finds two identical definitions it doesn't know which one to take and goes crazy.
But then how do you include the same header files in different sources?
Well that's why .h files have include guards, they ensure that the contents of an .h files are included by the linker only once in each Compilation.
Usually in the header file there is one of two possible ways to include these guards, there are very small differences between these two methods but they don't really apply if you're not doing some very specific stuff:
#pragma once
// Content of the header
or
#ifndef GUARD_H
#define GUARD_H
// Content of header
#endif
Where GUARD_H should be different for every .h file, usually it's a combination of your Project and header file names just to make sure it's different to other guards that could exist in other headers.
That's also why you can't (and shouldn't) include Source files in your code, if you include a source file then you are at a high risk of including the same definition multiple times since they don't use include guards.
The C file gets stored normally in any folder you want and gets compiled with a gcc and ./a.out in the terminal
That's essentially what VS does, just instead of you choosing which files to add in the compilation VS takes automatically all the files in the same Solution or Project (depending which one you decide to build).
For convenience, if you are just starting to learn, create a new solution for each Project (so for every main()) that you want.
Is this better or worse than using a simple text editor? Well, after the first 10-15 minutes of learning you'll see that it's much faster and useful to use an actual IDE as it provides many features that will make you write code faster and with less errors.
This is a really quick explanation of how things work in general. If you can, try to find someone IRL that can explain these things to you. It's really hard to explain it on the internet but it will take less than 10 minutes being together in front of the same computer.

How to delete dead code or code of no use based on configure file/makefile file

When we compile a C/C++ project, some files and codes in the project source are not needed for compilation. For example, test folder (some testing scripts), examples folder and dead code. How can I recognize these source files that are not compiled to binary files? It is not hoped that compiling is necessary. Cause I need to process many projects automatically and it is really hard to compile all projects without manual operations.
I know compilation can delete dead code automatically, but in my situation I can not compile the whole project, and in the source, there are many other codes that are not involved in final compilation such as code in test folder, tools folder... I hope to detect these code, as for dead code, I know its hard to detect it by static analysis, so disregard it, just care about whole files and whole folders that are not compiled.
Why I want to do this?
I want to extract some features (strings, function call graph, int constants... ) to represent this project and compare this features with the same features extracted from binary files to see what differences are there. So, if I extract features from code in test folder and the code are not compiled in the final binary files. There will be a big error when comparing these features.
Dead code would often -but not always- be eliminated by the compiler, when you ask it to optimize (but removing all dead code automatically is impossible, since undecidable because of equivalence with the halting problem). Be aware of the as-if rule permitting the compiler to do such optimizations. So in practice you don't need to remove the corresponding source code.
Some industries have as a coding rule (e.g. in DO-178C) the requirement that dead source code is forbidden. Detecting that is extremely difficult and in general impossible (see e.g. Rice's theorem), so requires a lot of sophisticated static program analysis techniques and external code review and costs a big lot (e.g. increase the cost of software development by more than 30x).
Your build automation system (e.g. cmake or Makefile, etc...) might be (and usually is) Turing-complete; so even removing entirely useless C++ source files is an impossible task in general. Even the POSIX shell (used in commands to build your thing) is difficult to analyze (see the excellent Parsing Posix [S]hell talk by Yann Regis-Gianas at FOSDEM2018).

Confusion about including .c and .h files

Recently I have been working with the TIVA C series launchpad board which has a Cortex-M4 chip on it. I use the Code Composer Studio as my IDE.
There is a lot of confusion going on right now because through trial and error I see that in order to use certain functions that the chip manufacturer provides, I will need to include the .c file instead of including the .h file.
This caught me off guard and I admit that I am not an expert programmer or an expert when it comes to compiler design. But does anyone know why a compiler would need the .c file instead of needing the .h file?
The .h file is still being used since it has definitions in it that the .c file requires.
Perhaps a better question may be this:
When there is a .h file and a .c file, do you include the .c file in your code or do you include the .h file?
My trial and error exercise is telling me that you must include the .c file but I am totally in the blind on what the actual rules are.
Sorry if any part of this is too vague. I would be totally fine with sharing my main.c file so you can see how I included the files but I felt that my question is more of a question regarding what the general rules are for including files when there is both a .h and a .c file.
Thank you for any time you can give me in helping me understand this issue.
EDIT: Why the down votes? I thought coming here for help was what this place was about?
It is important to understand that substantially all C programs are built from multiple source files. Under some circumstances many of those sources are pre-compiled into one or more libraries, but it is quite common that building a C program will involve also building multiple C source files and linking those to each other and to appropriate libraries to produce the final result.
It is also important to understand that although C permits multiple compatible declarations of functions and file-scope variables, it permits only one definition of each distinct function or variable anywhere in an entire program. This is the primary reason for the convention of placing declarations into header files (ordinarily named with a .h extension). Any number of source files that contribute to a given program may #include the same header file, but at most one of them could #include the source file that contains the corresponding definitions, and then only if that file were not included directly in the build.
It may be possible to write your main source file so that it #includes the .c files containing all the needed definitions directly, in which case it is not necessary to include the headers, but you cannot have two separate source files doing that contribute to the same program if that produces duplicate function definitions. Ultimately, too, this approach may fail, for there can be limits on how large and complex a source file a given compiler can manage.
If there are header files accompanying the chip manufacturer's C source files, then your own source files should include only those headers. You should be able to build object files from such sources just fine. To build executable programs, however, you must also build the chip manufacturer's C sources, and link them to your own. It would be sensible to create a library containing the chip manufacturer's sources and to link that, but it would also work to build the needed source files directly for every program. Your IDE should have support for both options.

What, if any, are the disadvantages having a header file of header files?

I came onto a project that employs the method of using a header file MyProject.h that has all the headers of each .c file. Each .c file has their own header file that has #include "MyProject.h", whatever libraries are needed, and any other declarations necessary for the file.
To me it seems redundant and somewhat unnatural, but it compiles and subsequently runs as expected. My thought is that the compiler would be doing way more work than necessary and is possibly over-bloating the .exe. What are the disadvantages, if any, to doing this?
A subsequent question I have is, say I included a library like Time.h in one file using the above example. Will the compiler only build Time.h once into the binary or for every file now because of MyProject.h? What about with structs, enums, etc...?
To have such a header file is poor practice and bad design. The problem is that it will create a tight coupling dependency between every single file of your project, even if they are completely unrelated.
Good program design is to create autonomous modules that only include the resources they are using. They should do this from their own h files, to document exactly which dependencies a particular module has.
The main downside is increased build times. Every source file includes every header of the project, whether it needs it or not.
It's also conceptually unclean. A source file should include the headers it needs. It should be possible to search for a header's name to find the parts of the source code that uses these facilities. Minimizing unnecessary includes is evidence of a loosely coupled system. However, include-what-you-use is hard to enforce, because you cannot prevent transitive availability of facilities through headers in C.
It should not lead to increased executable size. Even if the headers contain code (which is rare in C, but common in C++), the linker should eliminate duplicates and remove unused code.
All previous answers were clear enough, but.
The main disadvantage of "one big header file" is the problem with code reusability. For example, you've created some module as a part of your application. Let's say, this module implements API for some hardware. And then you want to make another application, which should use this module.
In this case you have to remember which header files you have to include to compile this module, or, if you just copy your previous "big header file", it requires a lot of unnecessary third party libraries and header files.
Nobody wants to spend a lot of time to make some module working. It's much better if you can use it right out-of-the-box, isn't it?
Most of my libraries have one precompiled header containing external includes and one "main" header for each library that contains the precompiled header items + all the .h files for the library in question. All of my .cpp files first include the precompiled header and then the main header.
That's it. None of my other .h files have any includes in at all. My .cpp files only include these two headers. Other libraries that need to use the library will #include that same main header.
Doing this has greatly simplified header file headache/complexity issue for me though I would add that most of my libraries are relatively small in the grand scheme of things. I don't know if this would work for a very large (monster) project. Perhaps not.
The way this works is actually quite nice. Others above, concerned about "coupling" want to minimise it, but if you don't include any headers at all you're 100% uncoupled, even from your dependencies. If you want to reuse the class, use the library that contains it.
Simple.

XC8 Library organization and #defines across multiple source files

This is a complicated post so please be patient. I have tried to condense it as much as possible...
I am coming to XC8 from using a different tool chain for PIC microcontrollers. With the previous compiler, setting up and using my own libraries and using defines across those libraries seems to be much easier.
I want to write my own libraries of functions for re-use. I also want to store them all in a directory structure of my own choosing (this is so that they sync automatically between multiple machines and for various other reasons). Here is a simplified fictional file structure.
\projects\my_project //the current project directory
\some_other_directory\my_library\comms_lib //my communications library
\some_other_directory\my_library\adc_lib //my ADC library
Now let’s say for arguments sake that each of my libraries needs the __XTAL_FREQ definition. The frequency will likely be different for each project.
Here are my questions:
What is the best/most efficient way to tell the compiler where my library files are located?
Short of adding __XTAL_FREQ to every header file how do I make the define available to all of them?
Likely someone is going to say that it should be in a separate header file (let’s call it project_config.h). This file could then be located with each future project and changed accordingly. If the separate header file is the answer then question that follows is, how do I get the library headers (not in the same directory as the project) to reference the project_config.h file correctly for each new project?
Thanks in advance, Mark
If you are using MPLABX, you could consider making one or more library projects for your libraries, which can then be included from other MPLABX projects.
As for a global definition of __XTAL_FREQ, I'm thinking that it should be possible to pass a symbol definition to the command line, not sure though.

Resources