Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Many languages, such as Java, C#, do not separate declaration from implementation. C# has a concept of partial class, but implementation and declaration still remain in the same file.
Why doesn't C++ have the same model? Is it more practical to have header files?
I am referring to current and upcoming versions of C++ standard.
Backwards Compatibility - Header files are not eliminated because it would break Backwards Compatibility.
Header files allow for independent compilation. You don't need to access or even have the implementation files to compile a file. This can make for easier distributed builds.
This also allows SDKs to be done a little easier. You can provide just the headers and some libraries. There are, of course, ways around this which other languages use.
Even Bjarne Stroustrup has called header files a kludge.
But without a standard binary format which includes the necessary metadata (like Java class files, or .Net PE files) I don't see any way to implement the feature. A stripped ELF or a.out binary doesn't have much of the information you would need to extract. And I don't think that the information is ever stored in Windows XCOFF files.
I routinely flip between C# and C++, and the lack of header files in C# is one of my biggest pet peeves. I can look at a header file and learn all I need to know about a class - what it's member functions are called, their calling syntax, etc - without having to wade through pages of the code that implements the class.
And yes, I know about partial classes and #regions, but it's not the same. Partial classes actually make the problem worse, because a class definition is spread across several files. As far as #regions go, they never seem to be expanded in the manner I'd like for what I'm doing at the moment, so I have to spend time expanding those little plus's until I get the view right.
Perhaps if Visual Studio's intellisense worked better for C++, I wouldn't have a compelling reason to have to refer to .h files so often, but even in VS2008, C++'s intellisense can't touch C#'s
C was made to make writing a compiler easily. It does a LOT of stuff based on that one principle. Pointers only exist to make writing a compiler easier, as do header files. Many of the things carried over to C++ are based on compatibility with these features implemented to make compiler writing easier.
It's a good idea actually. When C was created, C and Unix were kind of a pair. C ported Unix, Unix ran C. In this way, C and Unix could quickly spread from platform to platform whereas an OS based on assembly had to be completely re-written to be ported.
The concept of specifying an interface in one file and the implementation in another isn't a bad idea at all, but that's not what C header files are. They are simply a way to limit the number of passes a compiler has to make through your source code and allow some limited abstraction of the contract between files so they can communicate.
These items, pointers, header files, etc... don't really offer any advantage over another system. By putting more effort into the compiler, you can compile a reference object as easily as a pointer to the exact same object code. This is what C++ does now.
C is a great, simple language. It had a very limited feature set, and you could write a compiler without much effort. Porting it is generally trivial! I'm not trying to say it's a bad language or anything, it's just that C's primary goals when it was created may leave remnants in the language that are more or less unnecessary now, but are going to be kept around for compatibility.
It seems like some people don't really believe that C was written to port Unix, so here: (from)
The first version of UNIX was written
in assembler language, but Thompson's
intention was that it would be written
in a high-level language.
Thompson first tried in 1971 to use
Fortran on the PDP-7, but gave up
after the first day. Then he wrote a
very simple language he called B,
which he got going on the PDP-7. It
worked, but there were problems.
First, because the implementation was
interpreted, it was always going to be
slow. Second, the basic notions of B,
which was based on the word-oriented
BCPL, just were not right for a
byte-oriented machine like the new
PDP-11.
Ritchie used the PDP-11 to add types
to B, which for a while was called NB
for "New B," and then he started to
write a compiler for it. "So that the
first phase of C was really these two
phases in short succession of, first,
some language changes from B, really,
adding the type structure without too
much change in the syntax; and doing
the compiler," Ritchie said.
"The second phase was slower," he said
of rewriting UNIX in C. Thompson
started in the summer of 1972 but had
two problems: figuring out how to run
the basic co-routines, that is, how to
switch control from one process to
another; and the difficulty in getting
the proper data structure, since the
original version of C did not have
structures.
"The combination of the things caused
Ken to give up over the summer,"
Ritchie said. "Over the year, I added
structures and probably made the
compiler code somewhat better --
better code -- and so over the next
summer, that was when we made the
concerted effort and actually did redo
the whole operating system in C."
Here is a perfect example of what I mean. From the comments:
Pointers only exist to make writing a compiler easier? No. Pointers exist because they're the simplest possible abstraction over the idea of indirection. – Adam Rosenfield (an hour ago)
You are right. In order to implement indirection, pointers are the simplest possible abstraction to implement. In no way are they the simplest possible to comprehend or use. Arrays are much easier.
The problem? To implement arrays as efficiently as pointers you have to pretty much add a HUGE pile of code to your compiler.
There is no reason they couldn't have designed C without pointers, but with code like this:
int i=0;
while(src[++i])
dest[i]=src[i];
it will take a lot of effort (on the compilers part) to factor out the explicit i+src and i+dest additions and make it create the same code that this would make:
while(*(dest++) = *(src++))
;
Factoring out that variable "i" after the fact is HARD. New compilers can do it, but back then it just wasn't possible, and the OS running on that crappy hardware needed little optimizations like that.
Now few systems need that kind of optimization (I work on one of the slowest platforms around--cable set-top boxes, and most of our stuff is in Java) and in the rare case where you might need it, the new C compilers should be smart enough to make that kind of conversion on its own.
In The Design and Evolution of C++, Stroustrup gives out one more reason...
The same header file can have two or more implementation files which can be simultaneously worked-upon by more than one programmer without the need of a source-control system.
This might seem odd these days, but I guess it was an important issue when C++ was invented.
If you want C++ without header files then I have good news for you.
It already exists and is called D (http://www.digitalmars.com/d/index.html)
Technically D seems to be a lot nicer than C++ but it is just not mainstream enough for use in many applications at the moment.
One of C++'s goals is to be a superset of C, and it's difficult for it to do so if it cannot support header files. And, by extension, if you wish to excise header files you may as well consider excising CPP (the pre-processor, not plus-plus) altogether; both C# and Java do not specify macro pre-processors with their standards (but it should be noted in some cases they can be and even are used even with these languages).
As C++ is designed right now, you need prototypes -- just as in C -- to statically check any compiled code that references external functions and classes. Without header files, you would have to type out these class definitions and function declarations prior to using them. For C++ not to use header files, you'd have to add a feature in the language that would support something like Java's import keyword. That'd be a major addition, and change; to answer your question of if it'd be practical: I don't think so--not at all.
Many people are aware of shortcomings of header files and there are ideas to introduce more powerful module system to C++.
You might want to take a look at Modules in C++ (Revision 5) by Daveed Vandevoorde.
Well, C++ per se shouldn't eliminate header files because of backwards compatibility. However, I do think they're a silly idea in general. If you want to distribute a closed-source lib, this information can be extracted automatically. If you want to understand how to use a class w/o looking at the implementation, that's what documentation generators are for, and they do a heck of a lot better a job.
There is value in defining the class interface in a separate component to the implementation file.
It can be done with interfaces, but if you go down that road, then you are implicitly saying that classes are deficient in terms of separating implementation from contract.
Modula 2 had the right idea, definition modules and implementation modules. http://www.modula2.org/reference/modules.php
Java/C#'s answer is an implicit implementation of the same (albeit object-oriented.)
Header files are a kludge, because header files express implementation detail (such as private variables.)
In moving over to Java and C#, I find that if a language requires IDE support for development (such that public class interfaces are navigable in class browsers), then this is maybe a statement that the code doesn't stand on its own merits as being particularly readable.
I find the mix of interface with implementation detail quite horrendous.
Crucially, the lack of ability to document the public class signature in a concise well-commented file independent of implementation indicates to me that the language design is written for convenience of authorship, rather convenience of maintenance. Well I'm rambling about Java and C# now.
One advantage of this separation is that it is easy to view only the interface, without requiring an advanced editor.
No language exists without header files. It's a myth.
Look at any proprietary library distribution for Java (I have no C# experience to speak of, but I'd expect it's the same). They don't give you the complete source file; they just give you a file with every method's implementation blanked ({} or {return null;} or the like) and everything they can get away with hiding hidden. You can't call that anything but a header.
There is no technical reason, however, why a C or C++ compiler could count everything in an appropriately-marked file as extern unless that file is being compiled directly. However, the costs for compilation would be immense because neither C nor C++ is fast to parse, and that's a very important consideration. Any more complex method of melding headers and source would quickly encounter technical issues like the need for the compiler to know an object's layout.
If you want the reason why this will never happen: it would break pretty much all existing C++ software. If you look at some of the C++ committee design documentation, they looked at various alternatives to see how much code it would break.
It would be far easier to change the switch statement into something halfway intelligent. That would break only a little code. It's still not going to happen.
EDITED FOR NEW IDEA:
The difference between C++ and Java that makes C++ header files necessary is that C++ objects are not necessarily pointers. In Java, all class instances are referred to by pointer, although it doesn't look that way. C++ has objects allocated on the heap and the stack. This means C++ needs a way of knowing how big an object will be, and where the data members are in memory.
Header files are an integral part of the language. Without header files, all static libraries, dynamic libraries, pretty much any pre-compiled library becomes useless. Header files also make it easier to document everything, and make it possible to look over a library/file's API without going over every single bit of code.
They also make it easier to organize your program. Yes, you have to be constantly switching from source to header, but they also allow you define internal and private APIs inside the implementations. For example:
MySource.h:
extern int my_library_entry_point(int api_to_use, ...);
MySource.c:
int private_function_that_CANNOT_be_public();
int my_library_entry_point(int api_to_use, ...){
// [...] Do stuff
}
int private_function_that_CANNOT_be_public() {
}
If you #include <MySource.h>, then you get my_library_entry_point.
If you #include <MySource.c>, then you also get private_function_that_CANNOT_be_public.
You see how that could be a very bad thing if you had a function to get a list of passwords, or a function which implemented your encryption algorithm, or a function that would expose the internals of an OS, or a function that overrode privileges, etc.
Oh Yes!
After coding in Java and C# it's really annoying to have 2 files for every classes. So I was thinking how can I merge them without breaking existing code.
In fact, it's really easy. Just put the definition (implementation) inside an #ifdef section and add a define on the compiler command line to compile that file. That's it.
Here is an example:
/* File ClassA.cpp */
#ifndef _ClassA_
#define _ClassA_
#include "ClassB.cpp"
#include "InterfaceC.cpp"
class ClassA : public InterfaceC
{
public:
ClassA(void);
virtual ~ClassA(void);
virtual void methodC();
private:
ClassB b;
};
#endif
#ifdef compiling_ClassA
ClassA::ClassA(void)
{
}
ClassA::~ClassA(void)
{
}
void ClassA::methodC()
{
}
#endif
On the command line, compile that file with
-D compiling_ClassA
The other files that need to include ClassA can just do
#include "ClassA.cpp"
Of course the addition of the define on the command line can easily be added with a macro expansion (Visual Studio compiler) or with an automatic variables (gnu make) and using the same nomenclature for the define name.
Still I don't get the point of some statements. Separation of API and implementation is a very good thing, but header files are not API. There are private fields there. If you add or remove private field you change implementation and not API.
Related
In C++, your classes are often divided into two parts, being the header-file and the actual implementation. In my (unexperienced) opinion, this is awful. It requires me to do all sorts of unnecessary book-keeping, clutters up my project directory and goes against everything I've learned about software development (double implementation). Languages where you only deal with the implementation, such as Java or Python, are much nicer to work with.
I've always learned that the reason to use them was to significantly decrease compilation time. However, wouldn't a modern IDE (CLion in my case) or even the compiler be smart enough to either:
Keep some sort of "shadow"-header file, which would automatically be updated whenever a definition is changed in the implementation?
Automatically split it into the header and implementation during compile time, allowing you to only have to deal with one file? (Something that Lazy C++ seems to do)
Or are there any plugins available that offer this kind of behaviour? C++ modules also seem to offer a solution to this problem, but their current status/support is unclear to me and to make matters worse there seem to be two competing standards (Clang's and Microsoft's).
Unfortunately it is not that simple. Header/source file separation C++ inherited from C due to preprocessor, that both share. Automatic generation of a header file is not possible in general, first of all that separation is not trivial, second header file often has preprocessor code that manually written and generates compilation code. Third almost all templated code goes to a header file due to process of compilation and rules of visibility. Changing all of that would require breaking compatibility with existing code, amount of which is significant and nobody wants to do that. More easy would be to create yet another language (like D) but many people would not want to migrate due to various reasons. We know that committee is working on modules and if they manage to make them work without breaking compatibility, that would be helpful for many of us. But again this is not trivial task at all, the way you describe it would only work in certain environments (when you limit yourself) but cannot be applied to everybody.
C++ was the the first language I've learnt so dividing source code into .h and .cpp files seemed obvious - but having learnt C# and Java they now appear to me terribly clumsy. They might have been useful back in the 60s, maybe still even in 80s, but in the era of modern tools, such as IDEs with section folding, and documentation generators, they seem obsolete.
Anyway, my question is: is there a tool which makes the presence of these two kind of files transparent to the programmer? For example by letting the coder write the definition of a method seemingly in the header file but actually saving it to the .cpp file?
(I know one can try to write a C++ program solely in header files but AFAIK this is not considered best practice, makes the program build even longer and makes it virtually impossible for two classes to reference each other.)
The discussion that I am seeing in the question, comments and the comments to the other answer seem to focus on the textual representation of the components. From the point of view of plain text, it makes sense to remove the headers altogether.
On the other hand, there is a second level to the separation of headers and cpp files, which is separating the interface from the implementation, and in doing so, removing implementation details from the interface.
This happens in different ways, in the simplest level how you implement a particular piece of functionality is irrelevant to the users of your component[*]. In many cases, you can have more types and functions in the .cpp file that are used just as details of implementation. Additionally, if you decide to implement a particular functionality directly or by depending on another library is a detail of implementation and should not leak to your users.
That separation might or might not be easy to implement in a tool that managed the separation of files automatically, and cannot be done by those that like the use of header only libraries.
Where some of you are claiming that there is no point in having to Go to definition, and would like to see the code altogether, what I see is the flexibility of deciding what parts of your component are details that should not be known by users. In many IDEs (and, heck, even in vim) there is a single keystroke combination that will take you from one to the other. In IDEs you can refactor the signature of the function and have the IDE apply the changes to both the header and the implementation (sometimes even to the uses)...
If you were to have a tool provide a unified view of both the header and implementation, it would probably be much harder to make the tool knowledgable of what parts of the code you are writing are part of the interface or the implementation, and the decisions that the tool might have could have an impact on the generated program.
The separate compilation model has its disadvantages but also advantages, and I feel that the discussion that is being held here is just scratching the surface of deeper design decisions.
[*] There seems to be quite a few people that believe that each class should have its own header and .cpp files, and I disagree, each header represents a component that might be a single class, or multiple classes and free functions the separation of code in files is part of the design, and in a single component you might have one or more public types together with possibly none or more internal types.
I don't know of any that makes the division into source/header completely transparent.
I do, however, know of some that make it considerably easier to handle. For example, Visual Assist X will let write your entire class in a header, then select member functions, and move them to a source file (i.e., a .cpp file).
That's not a complete cure (by any means), but it can/does make them much more bearable anyway.
Personally, I think it would be interesting to get rid of files completely, and instead use something like a database directly -- i.e., you have a database of functions, where the source code to that function is one column, object code another, internal compiler information about how to use it yet another, and so on. This would also make integrating version control pretty straightforward (basically just a stored transaction log).
I, for one, like the header files in C++, because they can serve as a "table of contents" of a sort, which gives you a quick overview of a class. This is, of course, assuming that you keep your headers short, and put the implementation of most functions into the .cpp.
Also, you can get plugins for Visual Studio that will move the implementation of a member function from the header into a .cpp for you. That, plus the "go to definition" and "go to declaration" commands in Visual Studio make headers very helpful for navigating a large code base.
Headers are pretty fundamental to the current compilation model of C++. I think there are things that would be a bit difficult to express without exposing the programmer directly to the header/cpp split. For example, in certain circumstances there's a significant difference between:
// header
class Foo {
Foo() = default;
}
and
// header
class Foo {
Foo();
};
// cpp
Foo::Foo() = default;
Despite that I think it would be worthwhile to think about improving the compilation model or making it easier to deal with.
For example, I can imagine a 'code bubbles' style IDE where the programmer writes definitions in code bubbles, and then groups bubbles together into translation units. The programmer would mark definitions as 'exported' to make them available to other TUs and for each TU he'd select exported items from other units to import. And all the while the IDE is maintaining it's own code bubble representation of the program, and when you build it generates the actual cpp files necessary for passing off to the compiler, creating forward declarations, etc. as needed. The cpp files would just be an intermediate build product.
There would be subtleties like the one I showed above though, and I'm not sure how the IDE I described would deal with that.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Should C++ eliminate header files?
In languages like C# and Java there is no need to declare (for example) a class before using it. If I understand it correctly this is because the compiler does two passes on the code. In the first it just "collects the information available" and in the second one it checks that the code is correct.
In C and C++ the compiler does only one pass so everything needs to be available at that time.
So my question basically is why isn't it done this way in C and C++. Wouldn't it eliminate the needs for header files?
The short answer is that computing power and resources advanced exponentially between the time that C was defined and the time that Java came along 25 years later.
The longer answer...
The maximum size of a compilation unit -- the block of code that a compiler processes in a single chunk -- is going to be limited by the amount of memory that the compiling computer has. In order to process the symbols that you type into machine code, the compiler needs to hold all the symbols in a lookup table and reference them as it comes across them in your code.
When C was created in 1972, computing resources were much more scarce and at a high premium -- the memory required to store a complex program's entire symbolic table at once simply wasn't available in most systems. Fixed storage was also expensive, and extremely slow, so ideas like virtual memory or storing parts of the symbolic table on disk simply wouldn't have allowed compilation in a reasonable timeframe.
The best solution to the problem was to chunk the code into smaller pieces by having a human sort out which portions of the symbol table would be needed in which compilation units ahead of time. Imposing a fairly small task on the programmer of declaring what he would use saved the tremendous effort of having the computer search the entire program for anything the programmer could use.
It also saved the compiler from having to make two passes on every source file: the first one to index all the symbols inside, and the second to parse the references and look them up. When you're dealing with magnetic tape where seek times were measured in seconds and read throughput was measured in bytes per second (not kilobytes or megabytes), that was pretty meaningful.
C++, while created almost 17 years later, was defined as a superset of C, and therefore had to use the same mechanism.
By the time Java rolled around in 1995, average computers had enough memory that holding a symbolic table, even for a complex project, was no longer a substantial burden. And Java wasn't designed to be backwards-compatible with C, so it had no need to adopt a legacy mechanism. C# was similarly unencumbered.
As a result, their designers chose to shift the burden of compartmentalizing symbolic declaration back off the programmer and put it on the computer again, since its cost in proportion to the total effort of compilation was minimal.
Bottom line: there have been advances in compiler technology that make forward declarations unnecessary. Plus computers are thousands of times faster, and so can make the extra calculations necessary to handle the lack of forward declarations.
C and C++ are older and were standardized at a time when it was necessary to save every CPU cycle.
No, it would not obviate header files. It would eliminate the requirement to use a header to declare classes/functions in the same file. The major reason for headers is not to declare things in the same file though. The primary reason for headers is to declare things that are defined in other files.
For better or worse, the rules for the semantics of C (and C++) mandate the "single pass" style behavior. Just for example, consider code like this:
int i;
int f() {
i = 1;
int i = 2;
}
The i=1 assigns to the global, not the one defined inside of f(). This is because at the point of the assignment, the local definition of i hasn't been seen yet so it isn't taken into account. You could still follow these rules with a two-pass compiler, but doing so could be non-trivial. I haven't checked their specs to know with certainty, but my immediate guess would be that Java and C# differ from C and C++ in this respect.
Edit: Since a comment said my guess was incorrect, I did a bit of checking. According to the Java Language Reference, §14.4.2, Java seems to follow pretty close to the same rules as C++ (a little different, but not a whole lot.
At least as I read the C# language specification, (warning: Word file) however, it is different. It (§3.7.1) says: "The scope of a local variable declared in a local-variable-declaration (§8.5.1) is the block in which the declaration occurs."
This appears to say that in C#, the local variable should be visible throughout the entire block in which it is declared, so with code similar to the example I gave, the assignment would be to the local variable, not the global.
So, my guess was half right: Java follows (pretty much0 the same rule as C++ in this respect, but C# does not.
This is because of smaller compilation modules in C/C++. In C/C++, each .c/.cpp file is compiled separately, creating an .obj module. Thus the compiler needs the information about types and variables, declared in other compilation modules. This information is supplied in form of forward declarations, usually in header files.
C#, on the other side, compiles several .cs files into one big compilation module at once.
In fact, when referencing different compiled modules from a C# program, the compiler needs to know the declarations (type names etc.) the same way as C++ compiler does. This information is obtained from the compiled module directly. In C++ the same information is explicitly separated (that's why you cannot find out the variable names from C++-compiled DLL, but can determine it from .NET assembly).
The forward declarations in C++ are a way to provide metadata about the other pieces of code that might be used by the currently compiled source to the compiler, so it can generate the correct code.
That metadata can come from the author of the linked library/component. However, it can also be automatically generated (for example there are tools that generate C++ header files for COM objects). In any case, the C++ way of expressing that metadata is through the header files you need to include in your source code.
The C#/.Net also consume similar metadata at compile time. However, that metadata is automatically generated when the assembly it applies to is built and is usually embedded into it. Thus, when you reference in your C# project an assembly, you are essentially telling the compiler "look for the metadata you need in this assembly as well, please".
In other words, the metadata generation and consumption in C# is more transparent to the developers, allowing them to focus on what really matters - writing their own code.
There are also other benefits to having the metadata about the code bundled with the assembly as well. Reflection, code emitting, on-the-fly serialization - they all depend on the metadata to be able to generate the proper code at run-time.
The C++ analogue to this would be RTTI, although it's not widely-adopted due ot incompatible implementations.
From Eric Lippert, blogger of all things internal to C#: http://blogs.msdn.com/ericlippert/archive/2010/02/04/how-many-passes.aspx:
The C# language does not require that
declarations occur before usages,
which has two impacts, again, on the
user and on the compiler writer. [...]
The impact on the compiler writer is
that we have to have a “two pass”
compiler. In the first pass, we look
for declarations and ignore bodies.
Once we have gleaned all the
information from the declarations that
we would have got from the headers in
C++, we take a second pass over the
code and generate the IL for the
bodies.
To sum up, using something does not require declaring it in C#, whereas it does in C++. That means that in C++, you need to explicitly declare things, and it's more convenient and safe to do that with header files so you don't violate the One Definition Rule.
I don't quite understand the point of having a header; it seems to violate the DRY principle! All the information in a header is (can be) contained in the implementation.
It simplifies the compilation process. When you want to compile units independently, you need something to describe the parts that will be linked to without having to import the entirety of all the other files.
It also allows for code hiding. One can distribute a header to allow others to use the functionality without having to distribute the implementation.
Finally, it can encourage the separation of interface from implementation.
They are not the only way to solve these problems, but 30 years ago they were a good one. We probably wouldn't use header files for a language today, but they weren't invented in 2009.
The architects of many modern languages such as Java, Eiffel and C# clearly agree with you -- those languages extract the metadata about a module from the implementation. However, per se, the concept of headers doesn't preclude that -- it would obviously be a simple task for a compiler to extract a .h file while compiling a .c, for example, just like the compilers for those other languages do implicitly. The fact that typical current C compilers do not do it is not a language design issue -- it's an implementation issue; apparently there's no demand by users for such a feature, so no compiler vendor bothers implementing it.
As a language design choice, having separate .h files (in a human-readable and editable text format) gives you the best of both worlds: you can start separately compiling client code based on a module implementation that doesn't yet exist, if you wish, by writing the .h file by hand; or you (assuming by absurd a compiler implementation that supplies it;-) can get the .h file automatically from the implementation as a side effect of compiling it.
If C, C++, &c, keep thriving (apparently they're still doing fine today;-), and demand like yours for not manually writing headers grows, eventually compiler writers will have to supply the "header generation" option, and the "best of both worlds" won't stay theoretical!-)
It helps to think a bit about the capabilities of the computers that were available when, say c, was written. Main memory was measured in kilowords, and not necessarily very many of them. Disks were bigger, but not much. Serrious storage meant reel-to-reel tapes, mounted by hand, by grumpy operators, who really wanted you to go away so they could play hunt the wumpus. A 1 MIPS machine was screaming fast. And with all these limitation you had to share it. Possibly with a score of other users.
Anything that reduced the space or time complexity of compilation was a big win. And headers do both.
Don't forget the documentation a header provides. There is usually anything in it you need to know for using the module. I for my part don't want to scan through a looong sourcecode to learn what there is that I need to use and how to call it... You would extract this information anyway, which effectively results in -- a header file. No longer an issue with modern IDEs, of course, but working with some old C code I really love to have hand-crafted header files that include comments about the usage and about pre- and postconditions.
Keeping source, header and additional documentation in sync still is another can of worms...
The whole idea of inspecting the binary output files of language processors would have been hard to comprehend when C invented .h files. There was a system called JOVIAL that did something like it, but it was exotic and confined more-or-less exclusively to military projects. (I've never seen a JOVIAL program, I've only heard about it.)
So when C came out the usual design pattern for modularity was "no checks whatsoever". There might be a restriction that .text symbols could only link to .text and .data to .data, but that was it. That is, the compilers of the day typically processed one source file at a time and then linkers put them together without the slightest level of error checking other than, if you were lucky, "I'm a function symbol" vs "I'm a data symbol".
So the idea of actually having the compiler understand the thing you were calling was somewhat new.
Even today, if you make a totally bogus header, no one catches you in most AOT compilers. Clever things like CLR languages and Java actually do encode things in the class files.
So yes, in the long run, we probably won't have header files.
No you dont have headers in Java -- but you do have interfaces and I every serious Java guru recommends you define anything used by other projects/systems as an interface and an implementation.
Lets see a java interface definition contains call signatures, type definitions and contants.
MOST C header files contain call signatures, type definitions and constants.
So for all pratical purposes C/C++ header files are just interface definitions and should thus be considered a Good Thing. Now I know its possible to define a myriad other things in header files as well (MARCROs, constants etc. etc. ) but that just part of the whole wonderful world of C:-
int function target () {
// Default for shoot
return FOOT;
}
For Detail Read this
A header file commonly contains forward declarations of classes, subroutines, variables, and other identifiers. Programmers who wish to declare standardized identifiers in more than one source file can place such identifiers in a single header file, which other code can then include whenever the header contents are required.
The C standard library and C++ standard library traditionally declare their standard functions in header files.
And what if you want to give somebody else the declarations to use your library without giving them the implementation?
As another answer points out - the original reason for headers was to make the parse/compile easier on platforms with very simple and limited tools. It was a great step forward to have a machine with 2 floppies so you could have the compiler on one and your code on the other - made things a lot easier.
When you divide code in header and source files you divide declaration and definition. When you look in header files you can see what you have and if you wand to see implementation details you go to source file.
Is there any way to not have to write function declarations twice (headers) and still retain the same scalability in compiling, clarity in debugging, and flexibility in design when programming in C++?
Use Lzz. It takes a single file and automatically creates a .h and .cpp for you with all the declarations/definitions in the right place.
Lzz is really very powerful, and handles 99% of full C++ syntax, including templates, specializations etc etc etc.
Update 150120:
Newer C++ '11/14 syntax can only be used within Lzz function bodies.
I felt the same way when I started writing C, so I also looked into this. The answer is that yes, it's possible and no, you don't want to.
First with the yes.
In GCC, you can do this:
// foo.cph
void foo();
#if __INCLUDE_LEVEL__ == 0
void foo() {
printf("Hello World!\n");
}
#endif
This has the intended effect: you combine both header and source into one file that can both be included and linked.
Then with the no:
This only works if the compiler has access to the entire source. You can't use this trick when writing a library that you want to distribute but keep closed-source. Either you distribute the full .cph file, or you have to write a separate .h file to go with your .lib. Although maybe you could auto-generate it with the macro preprocessor. It would get hairy though.
And reason #2 why you don't want this, and that's probably the best one: compilation speed. Normally, C sources files only have to be recompiled when the file itself changes, or any of the files it includes changes.
The C file can change frequently, but the change only involves recompiling the one file that changed.
Header files define interfaces, so they shouldn't change as often. When they do however, they trigger a recompile of every source file that includes them.
When all your files are combined header and source files, every change will trigger a recompile of all source files. C++ isn't known for its fast compile times even now, imagine what would happen when the entire project had to be recompiled every time. Then extrapolate that to a project of hundreds of source files with complicated dependencies...
Sorry, but there's no such thing as a "best practice" for eliminating headers in C++: it's a bad idea, period. If you hate them that much, you have three choices:
Become intimately familiar with C++ internals and any compilers you're using; you're going to run into different problems than the average C++ developer, and you'll probably need to solve them without a lot of help.
Pick a language you can use "right" without getting depressed
Get a tool to generate them for you; you'll still have headers, but you save some typing effort
In his article Simple Support for Design by Contract in C++, Pedro Guerreiro stated:
Usually, a C++ class comes in two
files: the header file and the
definition file. Where should we write
the assertions: in the header file,
because assertions are specification?
Or in the definition file, since they
are executable? Or in both, running
the risk of inconsistency (and
duplicating work)? We recommend,
instead, that we forsake the
traditional style, and do away with
the definition file, using only the
header file, as if all functions were
defined inline, very much like Java
and Eiffel do.
This is such a drastic
change from the C++ normality that it
risks killing the endeavor at the
outset. On the other hand, maintaining
two files for each class is so
awkward, that sooner or later a C++
development environment will come up
that hides that from us, allowing us
to concentrate on our classes, without
having to worry about where they are
stored.
That was 2001. I agreed. It is 2009 now and still no "development environment that hides that from us, allowing us to concentrate on our classes" has come up. Instead, long compile times are the norm.
Note: The link above seems to be dead now. This is the full reference to the publication, as it appears in the Publications section of the author's website:
Pedro Guerreiro, Simple Support for Design by Contract in C++, TOOLS USA 2001, Proceedings, pages 24-34, IEEE, 2001.
There is no practical way to get around headers. The only thing you could do is to put all code into one big c++ file. That will end up in an umaintainable mess, so please don't do it.
At the moment C++ header-files are a nessesary evil. I don't like them, but there is no way around them. I'd love to see some improvements and fresh ideas on the problem though.
Btw - once you've got used to it it's not that bad anymore.. C++ (and any other language as well) has more anoying things.
What I have seen some people like you do is write everything in the headers. That gives your desired property of only having to write the method profiles once.
Personally I think there are very good reasons why it is better to separate declaration and definition, but if this distresses you there is a way to do what you want.
There's header file generation software. I've never used it, but it might be worth looking into. For instance, check out mkhdr! It supposedly scans C and C++ files and generates the appropriate header files.
(However, as Richard points out, this seems to limit you from using certain C++ functionality. See Richard's answer instead here right in this thread.)
You have to write function declaration twice, actually (once in header file, once in implementation file). The definition (AKA implementation) of the function will be written once, in the implementation file.
You can write all the code in header files (it is actually a very used practice in generic programming in C++), but this implies that every C/CPP file including that header will imply recompilation of the implementation from those header files.
If you are thinking to a system similar to C# or Java, it is not possible in C++.
Nobody has mentioned Visual-Assist X under Visual Studio 2012 yet.
It has a bunch of menus and hotkeys that you can use to ease the pain of maintaining headers:
"Create Declaration" copies the function declaration from the current function into the .hpp file.
"Refactor..Change signature" allows you to simultaneously update the .cpp and .h file with one command.
Alt-O allows you to instantly flip between .cpp and .h file.
C++ 20 modules solve this problem. There is no need for copy-pasting anymore! Just write your code in a single file and export things using "export".
export module mymodule;
export int myfunc() {
return 1
}
Read more about modules here: https://en.cppreference.com/w/cpp/language/modules
At the time of writing this answer (2022 Feb), these compilers support it:
See here for the supported compilers:
https://en.cppreference.com/w/cpp/compiler_support
See this answer if you want to use modules with CMake:
https://stackoverflow.com/a/71119196/7910299
Actually... You can write the entire implementation in a file. Templated classes are all defined in the header file with no cpp file.
You can also save then with whatever extensions you want. Then in #include statements, you would include your file.
/* mycode.cpp */
#pragma once
#include <iostreams.h>
class myclass {
public:
myclass();
dothing();
};
myclass::myclass() { }
myclass::dothing()
{
// code
}
Then in another file
/* myothercode.cpp */
#pragma once
#include "mycode.cpp"
int main() {
myclass A;
A.dothing();
return 0;
}
You may need to setup some build rules, but it should work.
You can avoid headers. Completely. But I don't recommend it.
You'll be faced with some very specific limitations. One of them is you won't be able to have circular references (you won't be able to have class Parent contain a pointer to an instance of class ChildNode, and class ChildNode also contain a pointer to an instance of class Parent. It'd have to be one or the other.)
There are other limitations which just end up making your code really weird. Stick to headers. You'll learn to actually like them (since they provide a nice quick synopsis of what a class can do).
To offer a variant on the popular answer of rix0rrr:
// foo.cph
#define INCLUDEMODE
#include "foo.cph"
#include "other.cph"
#undef INCLUDEMODE
void foo()
#if !defined(INCLUDEMODE)
{
printf("Hello World!\n");
}
#else
;
#endif
void bar()
#if !defined(INCLUDEMODE)
{
foo();
}
#else
;
#endif
I do not recommend this, bit I think this construction demonstrates the removal of content repetition at the cost of rote repetition. I guess it makes copy-pasta easier? That's not really a virtue.
As with all the other tricks of this nature, a modification to the body of a function will still require recompilation of all files including the file containing that function. Very careful automated tools can partially avoid this, but they would still have to parse the source file to check, and be carefully constructed to not rewrite their output if it's no different.
For other readers: I spent a few minutes trying to figure out include guards in this format, but didn't come up with anything good. Comments?
I understand your problems. I would say that the C++ main problem is the compilation/build method that it inherited from the C. The C/C++ header structure has been designed in times when coding involved less definitions and more implementations. Don't throw bottles on me, but that's how it looks like.
Since then the OOP has conquered the world and the world is more about definitions then implementations. As the result, including headers makes pretty painful to work with a language where the fundamental collections such as the ones in the STL made with templates which are notoriously difficult job for the compiler to deal with. All those magic with the precompiled headers doesn't help so much when it comes to TDD, refactoring tools, the general development environment.
Of course C programmers are not suffering from this too much since they don't have compiler-heavy header files and so they are happy with the pretty straightforward, low-level compilation tool chain. With C++ this is a history of suffering: endless forward declarations, precompiled headers, external parsers, custom preprocessors etc.
Many people, however, does not realize that the C++ is the ONLY language that has strong and modern solutions for high- and low-level problems. It's easy to say that you should go for an other language with proper reflection and build system, but it is non-sense that we have to sacrifice the low-level programming solutions with that and we need to complicate things with low-level language mixed with some virtual-machine/JIT based solution.
I have this idea for some time now, that it would be the most cool thing on earth to have a "unit" based c++ tool-chain, similar to that in D. The problem comes up with the cross-platform part: the object files are able to store any information, no problem with that, but since on windows the object file's structure is different that of the ELF, it would be pain in the ass to implement a cross-platform solution to store and process the half-way-compilation units.
After reading all the other answers, I find it missing that there is ongoing work to add support for modules in the C++ standard. It will not make it to C++0x, but the intention is that it will be tackled in a later Technical Review (rather than waiting for a new standard, that will take ages).
The proposal that was being discussed is N2073.
The bad part of it is that you will not get that, not even with the newest c++0x compilers. You will have to wait. In the mean time, you will have to compromise between the uniqueness of definitions in header-only libraries and the cost of compilation.
As far as I know, no. Headers are an inherent part of C++ as a language. Don't forget that forward declaration allows the compiler to merely include a function pointer to a compiled object/function without having to include the whole function (which you can get around by declaring a function inline (if the compiler feels like it).
If you really, really, really hate making headers, write a perl-script to autogenerate them, instead. I'm not sure I'd recommend it though.
It's completely possible to develop without header files. One can include a source file directly:
#include "MyModule.c"
The major issue with this is one of circular dependencies (ie: in C you must declare a function before calling it). This is not an issue if you design your code completely top-down, but it can take some time to wrap ones head around this sort of design pattern if you're not used to it.
If you absolutely must have circular dependencies, one may want to consider creating a file specifically for declarations and including it before everything else. This is a little inconvenient, but still less pollution than having a header for every C file.
I am currently developing using this method for one of my major projects. Here is a breakdown of advantages I've experienced:
Much less file pollution in your source tree.
Faster build times. (Only one object file is produced by the compiler, main.o)
Simpler make files. (Only one object file is produced by the compiler, main.o)
No need to "make clean". Every build is "clean".
Less boiler plate code. Less code = less potential bugs.
I've discovered that Gish (a game by Cryptic Sea, Edmund McMillen) used a variation on this technique inside its own source code.
You can carefully lay out your functions so that all of the dependent functions are compiled after their dependencies, but as Nils implied, that is not practical.
Catalin (forgive the missing diacritical marks) also suggested a more practical alternative of defining your methods in the header files. This can actually work in most cases.. especially if you have guards in your header files to make sure they are only included once.
I personally think that header files + declaring functions is much more desirable for 'getting your head around' new code, but that is a personal preference I suppose...
You can do without headers. But, why spend effort trying to avoid carefully worked out best practices that have been developed over many years by experts.
When I wrote basic, I quite liked line numbers. But, I wouldn't think of trying to jam them into C++, because that's not the C++ way. The same goes for headers... and I'm sure other answers explain all the reasoning.
For practical purposes no, it's not possible. Technically, yes, you can. But, frankly, it's an abuse of the language, and you should adapt to the language. Or move to something like C#.
It is best practice to use the header files, and after a while it will grow into you.
I agree that having only one file is easier, but It also can leed to bad codeing.
some of these things, althoug feel awkward, allow you to get more then meets the eye.
as an example think about pointers, passing parameters by value/by reference... etc.
for me the header files allow-me to keep my projects properly structured
Learn to recognize that header files are a good thing. They separate how codes appears to another user from the implementation of how it actually performs its operations.
When I use someone's code I do now want to have to wade through all of the implementation to see what the methods are on a class. I care about what the code does, not how it does it.
This has been "revived" thanks to a duplicate...
In any case, the concept of a header is a worthy one, i.e. separate out the interface from the implementation detail. The header outlines how you use a class / method, and not how it does it.
The downside is the detail within headers and all the workarounds necessary. These are the main issues as I see them:
dependency generation. When a header is modified, any source file that includes this header requires recompilation. The issue is of course working out which source files actually use it. When a "clean" build is performed it is often necessary to cache the information in some kind of dependency tree for later.
include guards. Ok, we all know how to write these but in a perfect system it would not be necessary.
private details. Within a class, you must put the private details into the header. Yes, the compiler needs to know the "size" of the class, but in a perfect system it would be able to bind this in a later phase. This leads to all kinds of workaround like pImpl and using abstract base classes even when you only have one implementation just because you want to hide a dependency.
The perfect system would work with
separate class definition and declaration
A clear bind between these two so the compiler would know where a class declaration and its definition are, and would know what the size of a class.
You declare using class rather than pre-processor #include. The compiler knows where to find a class. Once you have done "using class" you can use that class name without qualifying it.
I'd be interested to know how D does it.
With regards to whether you can use C++ without headers, I would say no you need them for abstract base classes and standard library. Aside from that you could get by without them, although you probably would not want to.
Can I write C++ code without headers
Read more about C++, e.g. the Programming using C++ book then the C+11 standard n3337.
Yes, because the preprocessor is (conceptually) generating code without headers.
If your C++ compiler is GCC and you are compiling your translation unit foo.cc consider running g++ -O -Wall -Wextra -C -E foo.cc > foo.ii; the emitted file foo.ii does not contain any preprocessor directive, and could be compiled with g++ -O foo.ii -o foo-bin into a foo-bin executable (at least on Linux). See also Advanced Linux Programming
On Linux, the following C++ file
// file ex.cc
extern "C" long write(int fd, const void *buf, size_t count);
extern "C" long strlen(const char*);
extern "C" void perror(const char*);
int main (int argc, char**argv)
{
if (argc>1)
write(1, argv[1], strlen(argv[1]);
else
write(1, __FILE__ " has no argument",
sizeof(__FILE__ " has no argument"));
if (write(1, "\n", 1) <= 0) {
perror(__FILE__);
return 1;
}
return 0;
}
could be compiled using GCC as g++ ex.cc -O ex-bin into an executable ex-bin which, when executed, would show something.
In some cases, it is worthwhile to generate some C++ code with another program
(perhaps SWIG, ANTLR, Bison, RefPerSys, GPP, or your own C++ code generator) and configure your build automation tool (e.g. ninja-build or GNU make) to handle such a situation. Notice that the source code of GCC 10 has a dozen of C++ code generators.
With GCC, you might sometimes consider writing your own GCC plugin to analyze your (or others) C++ code (e.g. at the GIMPLE level). See also (in fall 2020) CHARIOT and DECODER European projects. You could also consider using the Clang static analyzer or Frama-C++.
Historically hearder files have been used for two reasons.
To provides symbols when compiling a program that wants to used a
library or a additional file.
To hide part of the implementing; keep things private.
For example say you have a function you don't want exposed to other
parts of your program, but want to use in your implementation. In that
case, you would write the function in the CPP file, but leave it out
of the header file. You can do this with variables and anything that
would want to keep private in the impregnation that you don't want
exposed to conumbers of that source code. In other programming
lanugases there is a "public" keyword that allows module parts to be
kept from being exposed to other parts of your program. In C and C++
no such facility exists at afile level, so header files are used
intead.
Header files are not perfect. Useing '#include' just copies the contents
of what ever file you provide. Single quotes for the current working
tree and < and > for system installed headers. In CPP for system
installed std components the '.h' is omitted; just another way C++
likes to do its own thing. If you want to give '#include' any kind of
file, it will be included. It really isn't a module system like Java,
Python, and most other programming lanuages have. Since headers are
not modules some extra steps need to be taken to get similar function
out of them. The Prepossesser (the thing that works with all the
#keywords) will blindly include what every you state is needed to be
consumed in that file, but C or C++ want to have your symbals or
implications defined only one in compilation. If you use a library, no
it main.cpp, but in the two files that main includes, then you only
want that library included once and not twice. Standard Library
components are handled special, so you don't need to worry about using
the same C++ include everywhere. To make it so that the first time the
Prepossesser sees your library it doesn't include it again, you need
to use a heard guard.
A heard guard is the simplest thing. It looks like this:
#ifndef LIBRARY_H
#define LIBRARY_H
// Write your definitions here.
#endif
It is considered good to comment the ifndef like this:
#endif // LIBRARY_H
But if you don't do the comment the compiler wont care and it wont
hurt anthing.
All #ifndef is doing is checking whether LIBRARY_H is equal to 0;
undefined. When LIBRARY_H is 0, it provides what comes before the
#endif.
Then #define LIBRARY_H sets LIBRARY_H to 1, so the next time the
Preprocessor sees #ifndef LIBRARY_H, it wont provide the same contents
again.
(LIBRARY_H should be what ever the file name is and then _ and the
extension. This is not going break anything if you don't write the
same thing, but you should be consistent. At least put the file name
for the #ifndef. Otherwise it might get confusing what guards are for
what.)
Really nothing fancy going on here.
Now you don't want to use header files.
Great, say you don't care about:
Having things private by excluding them from header files
You don't intend to used this code in a library. If you ever do, it
may be easier to go with headers now so you don't have to reorganise
your code into headers later.
You don't want to repeat yourself once in a header file and then in
a C++ file.
The purpose of hearder files can seem ambiguous and if you don't care
about people telling out it's wrong for imaginary reasons, then save
your hands and don't bother repeating yourself.
How to include only hearder files
Do
#ifndef THING_CPP
#define THING_CPP
#include <iostream>
void drink_me() {
std::cout << "Drink me!" << std::endl;
}
#endif // THING_CPP
for thing.cpp.
And for main.cpp do
#include "thing.cpp"
int main() {
drink_me();
return 0;
}
then compile.
Basically just name your included CPP file with the CPP extension and
then treat it like a header file but write out the implementations in
that one file.