Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't C/C++'s "#pragma once" an ISO standard?

I am currently working on a big project and maintaining all those include guards makes me crazy! Writing it by hand is frustrating waste of time. Although many editors can generate include guards this doesn't help much:

  1. Editor generates guard symbol based on a filename. The problem occurs when you have headers with the same filename in different directories. Both of them will get the same include guard. Including directory structure into the guard symbol would require some fancy approach from the editor, since slashes and backslashes in the macro are not the best thing.

  2. When I have to rename a file I should rename all the include guards as well (in the ifndef, define and ideally endif's comment). Annoying.

  3. Preprocessor is flooded with tons of symbols without a clue what they mean.

  4. Nevertheless definition is included once, compiler still opens header every time it meets header inclusion.

  5. Include guards don't fit into namespaces nor templates. In fact they are subverting namespaces!

  6. You have a chance that your guard symbol won't be unique.

Maybe they were acceptable solution in times when programs contained less than 1000 headers in single directory. But nowadays? It is ancient, it has nothing to do with modern coding habits. What bothers me the most is that this issues could be almost compeletly solved by #pragma once directive. Why is it not a standard?

like image 359
mip Avatar asked Nov 08 '09 08:11

mip


People also ask

Why is CCS controversial?

But investing in CCS is controversial because, although some consider it a critical climate mitigation technology, others view it as an expensive fossil fuel subsidy that could inadvertently perpetuate, rather than reduce, fossil fuel reliance.

Why is carbon capture so difficult?

Carbon Capture is Energy Intensive Running a carbon capture system is incredibly energy-intensive — it essentially requires building a new power plant to run the system, which would create another new source of air and carbon pollution. That undermines the whole goal of capturing carbon in the first place.

Is CCS realistic?

“To put it briefly: Yes, it does work,” said Julio Friedmann, a senior research scholar at the Center on Global Energy Policy at Columbia University. He pointed out that industrial facilities that scrub carbon dioxide from their flue gas have reduced their life-cycle emissions of CO2 by 55 to 90 percent.

What is a major problem with carbon capture and storage strategies?

In addition to high costs of capture technology, there are also challenges associated with transporting CO₂ once it is captured. Significant energy is required to compress and chill CO₂ and maintain high pressure and low temperatures throughout pipelines, and the pipelines themselves are expensive to build.


1 Answers

A directive like #pragma once is not trivial to define in a fully portable way that has clear an unambiguous benefits. Some of the concepts for which it raises questions are not well defined on all systems that support C, and defining it in a simple way might provide no benefit over conventional include guards.

When the compile encounters #pragma once, how should it identify this file so that it doesn't include its contents again?

The obvious answer is the unique location of the file on the system. This is fine if the system has unique locations for all files but many systems provide links (symlinks and hardlinks) that mean that a 'file' doesn't have a unique location. Should the file be re-included just because it was found via a different name? Probably not.

But now there is a problem, how is it possible to define the behaviour of #pragma once in a way that has an exact meaning on all platforms - even those that don't even have directories, let alone symlinks - and still get the desirable behaviour on systems that do have them?

You could say that a files identity is determined by its contents, so if an included file has a #pragma once and a file is included that has exactly the same contents, then the second and subsequent #includes shall have no effect.

This is easy to define and has well defined semantics. It also has good properties such that if a project is moved from a system that supports and uses filesystem links to one that doesn't, it still behaves the same.

On the downside, every time an include file is encountered containing a #pragma once its contents must be checked against every other file using #pragma once that has already been included so far. This implies a performance hit similar to using #include guards in any case and adds a not insignificant burden to compiler writers. Obviously, the results of this could be cached, but the same is true for conventional include guards.

Conventional include guards force the programmer to choose a macro that is the unique identifier for an include file, but at least the behaviour is well-defined and simple to implement.

Given the potential pitfalls and costs, and the fact the conventional include guards do work, it is not surprising to me that the standards committee didn't feel the need to standardize #pragma once.

like image 52
CB Bailey Avatar answered Oct 21 '22 05:10

CB Bailey