arturo_drt
arturo_drt

Reputation: 23

Include .c instead of header(.h) - MISRA C

Is using #include "component.c" considered bad practice or is there any misra standard rule violation? (potentially rule 3-3-1)

So far, I understand that it is a commonly categorized as bad practice but can be used in certain scenarios, would it be any particular concern for safety-critical applications?

Misra rule 3-3-1 states that Objects or functions with external linkage shall be declared in a header file

Upvotes: 0

Views: 1149

Answers (5)

Andrew
Andrew

Reputation: 2312

Rule 3-1-1 is a MISRA C++:2008 rule

The applicable MISRA C:2012 guidelines are (probably) Rules 20.2 and 20.3 - which do not prohibit the use of .c extensions.

--

In MISRA C:2004, Rule 8.5 prohibited source code in a header file (assumed to be a .h file). This Rule was dropped for MISRA C:2012 to permit the use of inline functions.

--

Personally, I think #include-ing a .c file is a bad idea - it suggests a mis-understanding of the language, the compiler and the linker.

If you do so, the expanded file would count as a Single Translation Unit for analysis purposes...

(see profile for Affiliation)

Upvotes: 0

John Bollinger
John Bollinger

Reputation: 180266

Is using #include "component.c" considered bad practice

Generally speaking, yes.

Usually, the preprocessor's file-inclusion feature is reserved to support factoring common declarations into their own files, so that they don't need to be duplicated in multiple sources. Such factoring provides huge benefits for maintainability in all but the smallest projects, and it is a near-requirement for libraries to be usable. A file containing only such declarations is conventionally called a "header", and is conventionally named with a .h suffix. In this sense, then, the issue is partially about file naming and programming patterns.

On the other hand, C source files containing function or object definitions (as opposed to declarations) are conventionally named with a .c suffix. The C language forbids multiple external definitions of the same identifier (function or variable name) in the same program, so such .c files cannot be #included into more than one translation unit contributing to a program, and if they are included into even one, then they must not also be compiled directly. The usual way to build a program from multiple .c files is to compile them independently and then link them together.

Provided one is sure to avoid duplicate definitions, it is not inherently wrong to #include one .c file into another. But this makes sense only as a special-purpose arrangement. It creates extra risk, and it provides no particular advantage as far as the language specification goes. Also, because it runs contrary to convention, it tends to surprise and confuse developers -- maybe even more experienced future you.

is there any misra standard rule violation? (potentially rule 3-3-1)

It does not inherently violate MISRA rule 3-3-1, but it makes it less painful to write code that does violate that rule. That is by making it feasible to have all the needed external declarations in a single .c file plus its inclusions, instead of providing a separate header.

I don't see any other MISRA-2012 rule that such an inclusion would violate. But that would not hold much water with me in code review.

Upvotes: 0

user1322654
user1322654

Reputation:

You are referencing the MISRA C++ standard not the MISRA C standard. In the MISRA C++ standard rule 3-1-1 does not restrict you from #include-ing C files in other C files, because any C file may include one another and not declare anything as having external linkage. The rule/requirement is about external linkage, not about C file inclusion. I believe that if they were to add a rule for including other C files it would be under section "Source file inclusion" rules 16-2-X, but i have just checked and there is nothing about including other C files. Personally, i dont mind including other C files because i see #include as just a copying and pasting operations to be used however you see fit.

Upvotes: 1

JimGav
JimGav

Reputation: 30

It is also a matter of security in terms that you might not want to provide your code, so you just give the header and the object files

Upvotes: 0

Jason
Jason

Reputation: 2671

When you write a program like that, it is called a unity build. A good example of such a program is the compiler for the Odin programming language. So it can be done, but like anything else, there are tradeoffs.

pros

  • It puts more source into a single translation unit. This can help optimization, similar to how link-time-optimization works since the compiler can actually see the source from functions in other C files.

  • Less clutter in project files (less headers), and therefor, less repetition.

  • A greatly simplified build; It may be as easy as building only one file even if many files are in the project.

cons

  • Harder to understand for co-workers who use more common practices.

  • You can no longer define a static variable with a very generic name in a C file, because that C file could be part of a bigger translation unit. You will wind up with more verbose variable names.

  • It will generally slow down the build. Build systems (like make), can speed up compilation by only re-compiling what is dependent on all changes. If you are combining things into a single translation unit, the whole thing will need to build for every change. In a big project, this will lead to more memory consumption during the build.

  • You cannot parallelize the build.

Does this violate MIRSA?

I don't actually know, but it doesn't violate the rule you posted:

Misra rule 3-3-1 states that Objects or functions with external linkage shall be declared in a header file

By including a C file, you know longer have external linkage because they are in the same translation unit.

Upvotes: 1

Related Questions