2

I have a question about the "AV Rule 33" in [1].

It says "The #include directive shall use the <filename.h> notation to include header files.".

The document "explains" it by "divergence in vendor implementations", but I have problems believing it. A "local header" file is a local header file?!

Do compiler differ that much in the definition of "local"?

[1] http://www.stroustrup.com/JSF-AV-rules.pdf

R Sahu
  • 204,454
  • 14
  • 159
  • 270
mjjoker
  • 119
  • 1
  • 6
  • Perhaps you know something of the _Joint Strike Fighter_ that we dont? Given that he's the author of the language, I'd be inclined to take his word on it when dealing with unit-costs of many millions of dollars and a program cost of 1.1 ***trillion*** dollars. I've seen similarly restrictive rules in place for those writing code for the automotive industry - the relevance being that one is not free to use whichever compiler one chooses, there are mandated tools. Hint: GCC and VS are not in the list, hence you're dealing with fairly small vendors, with more chance for divergence from standards. – enhzflep May 27 '15 at 06:44
  • Looks weird. Maybe the implementation for which the document was written supports searching in local directories for the `<>` notation and does smth crazy for the `""` notation? –  May 27 '15 at 06:45
  • Does the JSF allow code to be written in both C++ and C, or are the tags wrong? – Paul Hankin May 27 '15 at 06:45
  • The document is correct (the standard doesn't state it *has* to be the local file), but you could have found this by looking it up here. – Ami Tavory May 27 '15 at 06:47
  • Nothing is weird. The designer want only one way of finding header files. And it is . It is a design choice. An informed choice. – UmNyobe May 27 '15 at 06:48
  • @PaulHankin It's a weird document: it is a coding standard for C++ but it heavily cites MISRA-C:2004, which is a coding standard for C. (MISRA C++ had not been released when the JSF document was made) – Lundin May 27 '15 at 06:57
  • And I don't believe this is a duplicate as there is no explanation to the rationale behind the JSF document in that duplicate. I'll re-open this. – Lundin May 27 '15 at 06:58

3 Answers3

2

Seems like a strange rationale. At least in C, either form is implementation-specific.

C11 6.10.2 and C++03 16.2 seem 100% identical here:

A preprocessing directive of the form

# include <h-char-sequence> new-line

searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.

A preprocessing directive of the form

# include "q-char-sequence" new-line

causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read

# include <h-char-sequence> new-line

with the identical contained sequence (including > characters, if any) from the original directive.

As we can read in the standard(s), both forms use implementation-defined searches. The standard explicitly states that if #include "filename.h" fails, it will revert to treat it like #include <filename.h>". So the rationale doesn't make any sense.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 1
    But what if `#include "filename.h"` doesn't _fail_, but instead finds the wrong file? – davmac May 27 '15 at 07:23
  • @davmac Similarly, what if `#include ` finds the wrong file? Neither form guarantees anything. – Lundin May 27 '15 at 07:27
  • @Lundin but perhaps "divergence in vendor implementations" is not an issue with the latter form. Furthermore the standard guarantees the existence of certain headers which can be located using `#include `, i.e. the standard library headers. – davmac May 27 '15 at 07:27
  • reading the exact wording of the standard, the term "search" may be the reason for the rule. Searching implies findings of any number. Not really what a programmer expects when including a very specific file – mjjoker May 27 '15 at 07:31
  • @davmac The standard explicitly states that it is implementation-defined behavior, so if anyone expects anything else, they are confused. I don't even think this is an issue, because if you accidentally include the wrong include file, the program won't link. Unless I suppose you have multiple versions of the same h file scattered all over your hard drive. In which case a version control system is the solution, not obscure `#include` directives. – Lundin May 27 '15 at 07:32
  • I would suspect this is merely a goof-up when importing MISRA-C rules into the JSF document. MISRA-C has a much more sound rule 19.3: "The `#include` directive shall only be followed by either a `` or a `"filename"` sequence. – Lundin May 27 '15 at 07:33
  • @Lundin, expectations aside, the rationale is "divergence in vendor implementations", implying that this divergence is only an issue for one form of the statement and not the other. Given the full wording of the rationale, this seems quite deliberate. Putting it another way, the rule seems like it's due to observed behavior of implementations. What the standard says isn't really relevant. – davmac May 27 '15 at 07:35
  • @davmac I read _lots_ of safety standards like this and my experience is that there are always some things stated with no sound rationale behind them. In which case good engineering demands that you need to question the rule. Bad and dangerous engineering is to blindly following coding rules that don't make any sense to you. Such "blind coding" is actually becoming a problem for the embedded industry, now that most companies are actually serious enough to have coding standards. – Lundin May 27 '15 at 07:40
  • There may very well be a sound rationale behind the rule, but the text labelled "rationale" in the document is not a sufficient explanation. – Lundin May 27 '15 at 07:42
  • @Lundin I agree the rationale lacks detail, but your answer says that it _doesn't make sense_, which is not correct and which is what I take issue with. – davmac May 27 '15 at 14:59
  • @davmac Well, it doesn't make sense until proven otherwise. I would bet that someone at some point had some localized problem on system x with compiler y, originating from a poor choice of file names, as in the case described by Ike. Common sense would then be to enforce unique file names instead of enforcing obscure include syntax. – Lundin May 27 '15 at 15:08
  • @Lundin maybe we can agree that the rationale text (whether it makes sense or not) doesn't by itself fully justify the existence of the rule. I'm not against a rule regarding unique filenames as an addition; however, mistakes get made and if this rule would then prevent a divergence in behaviour between compilers in cases where a header file had been accidentally named the same as a system header (particularly given that a vendor might have their own system headers, whether doings so complieswith the standard or not), then I can see why it exists. – davmac May 27 '15 at 15:54
  • @davmac Mission-critical software gets checked with static analysis tools. Duplicate choice of file names would be a perfect thing to create automated tests for, if there was a rule against such. Then the programmer doesn't need to concern themselves at all, as long as they run the tests. – Lundin May 28 '15 at 06:28
2

I've worked with some compilers over 10 years ago which might warrant that kind of rationale. I'm not suggesting it's a good rationale and trying to defend it, but just want to clarify why it might have arisen.

Basically in our case, we tripped up because we had local project headers (for small projects like plugins) named with rather clashy names like simply rect.h or mem.h. We thought the use of local-style include directives would protect us from clashes, and it did on most compilers except one we encountered.

I can't remember exactly which compiler tripped us up (I think it was an old version of CodeWarrior, but my memory could be failing me). In any case, this compiler was treating:

#include "rect.h"

... synonymously with:

#include <rect.h>

Basically it made no difference in the former include style that rect.h was in the exact same directory as the source file including it. It still prioritized searching for header files in the order they appeared in the specified include paths for the project and compiler settings, so we got a lot of clashes there with standard headers and OS headers that we had little choice to resolve except by naming the header files better, less generally, in a less clash-prone way. Maybe we could have tried some other things like:

#include "./rect.h"

... perhaps that would have worked (though it looks a bit goofy). We might have also been able to try to force, through the project and compiler settings, the preprocessor to prioritize the project's own directory above all other include paths. We didn't try exhausting all possible solutions and just went for renaming our header files with a prefix convention we apply consistently to make avoiding conflicts more of a no-brainer without having to analyze things on a case-by-case basis.

This was especially awkward since we were getting it in a third party library outside of our control, and changing such code is pretty gross (ex: we might need to do it again with a new version of the library).

That's all we did. We didn't actually come up with a coding standard suggesting to avoid the former include style in favor of only using the latter, but I can see why someone might establish that rationale in response to a similar compiler issue.

The problem is that if we're targeting multiple platforms and use a wide variety of compilers and sometimes porting to new ones, we unfortunately have to target the lowest common denominator. If that lowest common denominator makes no distinction between #include "rect.h" and #include <rect.h>, then the idea that these two are different becomes an illusion on some compilers and a reality on others.

This inconsistency can be a source of confusion, and it might lead to less porting headaches to simply adopt the latter style everywhere to gain back that consistency and perhaps more quickly realize, in foresight rather than in hindsight after looking at a bunch of build errors from trying to port the code, to name headers in a less clashy way.

  • 1
    "that we had little choice to resolve except by naming the header files better, less generally, in a less clash-prone way" Renaming the headers is the actual solution to the problem. Because you simply can't allow two headers in the same application to have the same names, be they library headers or local ones. That's just stupid and nothing you should try to dodge and "engineer" your way around, particularly not in the mission-critical software for which the JSF standard was intended for. Generally, "engineering around" to avoid common sense is a very bad idea. – Lundin May 27 '15 at 08:45
  • Yes, that would be my conclusion as well, only I would add that it is _especially_ true when preprocessors have existed that treated the two include styles as virtually the same thing. We've since adopted a prefix convention we apply consistently for everything. Also we only had build errors and our software wasn't so mission-critical, but I could imagine scenarios where you didn't have a build error and had a runtime bug instead from the wrong header being used, and that would be far, far worse, especially in such a software. –  May 27 '15 at 08:50
0

The pdf clearly states

However, due to the unfortunate divergence in vendor implementations, only the < filename.h > form will be used.

By which he means that in order to include the files provided by vendors you should not do "filename.h" as it will only search in the local path only.

Vinay Shukla
  • 1,818
  • 13
  • 41
  • You say "to include the files provided by vendors", but the rule in no way limits the rule to files provided by vendors. The rule applies to _all_ header files: "The #include directive shall use the notation to _include header files._" – rodrigo May 27 '15 at 08:12