views:

397

answers:

9

After reading several questions regarding problems with compilation (particularly C++) and noticing that in many cases the problem is a missing header #include. I couldn't help to wonder in my ignorance and ask myself (and now to you):

Why are missing headers not automatically checked and added or requested to the programmer?

Such feature is available for Java import statements in Netbeans for example.

A: 

NetBeans is an IDE (Integrated Development Environment). Some C/C++ IDEs do have that feature...but not everybody knows about it or utilizes it.

Justin Niessner
+2  A: 

Because the second you trust the computer to think for you, you've got a major case of SkyNet on your hands.

Computers, in general, are very bad at making choices, except for very simple ones. Pulling something out of dependency hell simply isn't a task you should entrust it with, because that kind of thinking leads to sloppy coding and buggy code.

Williham Totland
+4  A: 

Last I remember, Java also throws error if an Import statement is missed. It is the NetBeans GUI that makes your life easier.

Probably you should try finding an intelligent GUI for your C/C++ code.

Bragboy
+7  A: 

Why are missing headers not automatically checked and added or requested to the programmer?

But they are automatically checked.

  1. My compiler fails compilation when it can't find a header.
  2. My IDE (eclipse) adds a visual clue when it can't find a header file I've #included, it underlines the #include line and provides a tooltip telling me what the problem is.

It won't automatically add an include because it can't know which include I forgot. Compilers aren't psychic.

Glen
A: 

Because in general it's a difficult problem to know which header files you need to include to define something properly. It would be quite a nice feature to have your IDE be able to guess simple cases and offer to help though.

John Burton
+10  A: 

Remember the clash in Java between java.util.Date and java.sql.Date? If someone uses Date in their code, you can't tell whether they forgot import java.util.Date or import java.sql.Date.

In both Java and C++, it is not possible to tell with certainty what import/include statement is missing. So neither language tries. Your IDE might make suggestions for undeclared symbols used in your code.

The problem is further complicated in C++, because the standard says that any standard header can include any other standard header(s). It's therefore very easy to use a function or class without directly including the header which defines it, because your compiler happens to include the right header indirectly. The resulting code works in some implementations but not others, according to whether they share that header dependency.

It's not in general possible for a C++ IDE to tell whether a header dependency is "guaranteed", or just an incidental implementation detail that users shouldn't rely on. Obviously for standard libraries it could just know what's defined in what headers, but as soon as you get to third party libraries it gets quite uncertain.

I think most C++ programmers expect to have to look up what headers define what symbols. With Java, the one-public-class-per-file rule simplifies this considerably, and you just import the packages/classes you want. C++ doesn't have packages, and the only way for the IDE to find a class called my_namespace::something::MyClass is to search for it in every header file.

Steve Jessop
thanks for you explanation steve
Carlucho
+1  A: 

The compiler shouldn't have to think for you. What if there is a function of the same name in two different libraries? How would it know which header to include and which library to link against? Having a compiler or IDE silently fixing your sloppy code is a bad idea in my opinion.

Glen
+1  A: 

Part of the difference is because of a few fundamental design decisions that were made differently between the two. In particular, Java requires that the name of a class match the name of the file, so the name of the class you use pretty much tells it what you needed to import.

In C or C++, the name you give to a header doesn't necessarily have to match the contents at all. If you wanted to badly enough, you could name your headers 1.h, 2.h, 3.h, and so on -- or even 1.bas, 2.pas, 3.java, 4.ada, and whatever other misleading names you happen to prefer. That's obviously a poor idea, but if you did it anyway, the compiler wouldn't be at all bothered.

As such, it's much more difficult for a C or C++ tool to guess at what header needs to be included to get the definition of a particular type. In theory, it could (for example) build a big database of all the functions, classes, types, etc., in all the headers you've written, and when you use one, tell you which header(s) define what names, but I'm not aware of an IDE that actually does so.

Jerry Coffin
+3  A: 

If I reference a function named sqrt, how does the compiler know which file to look in, if I haven't specified it? It could be absolutely any file on my entire harddrive.

Unlike Java, C++ doesn't really consider any files "special". Java has its giant (bloated) class library, which is automatically made accessible to the programmer.

In C++, this concept doesn't exist. You tell the compiler which paths to search in, and whenever you #include a file, it will search for the filename in those paths.

If that happens to find a standard library file, it'll use that. If it happens to find a third-party file, it'll use that.

The compiler doesn't know that sqrt is defined in the header math.h. Or that it is also typically defined in cmath In fact, the functions defined by a header might vary. Perhaps, if I #define the appropriate preprocessor symbol, some functions will be removed from a specific header, and others will be enabled.

But unlike Java, where the functions and classes defined by a library can be determined just by examining the library file's metadata, in C++, the header has to be compiled. And the result of compiling it might vary depending on the context in which it is included.

So the C++ compiler cannot guess at which header should be included in order to define the function you just used.

jalf
thanks buddy that makes a lot of sense
Carlucho