-3

When compiling a C++ source file, if you have multiple headers consisting of bracketed and quoted headers, do the bracketed headers have to always be listed first?

I put a quoted header before a bracketed header and this started giving me redefinition compiler errors.

The header file (utilities.h) is:

#ifndef _UTILITIES_H
#define _UTILITIES_H

#include <vector>
double calcNorm(std::vector <double> array);   //template?

#endif

The source file (utilities.cpp) is

#include <math.h>
#include <vector>
#include "utilities.h"

double calcNorm(std::vector <double> array)   //template?
{
   int n;
   double norm = 0;

   n = array.size();
   for (int i = 0; i < n; i++)
   {
      norm += array[i]*array[i];
   }

   norm = sqrt(norm);

   return norm;
}

Previously, in the source file, I had #include "utilities.h" above the bracketed headers and I was getting the following compiler error:

g++ -g -Wall -c utilities.cpp
utilities.cpp: In function ‘double calcNorm(std::vector<double>)’:
utilities.cpp:5:8: error: redefinition of ‘double calcNorm(std::vector<double>)’
 double calcNorm(std::vector <double> array)   //template?
        ^
utilities.h:3:8: note: ‘double calcNorm(std::vector<double>)’ previously defined here
makefile:12: recipe for target 'utilities.o' failed
24n8
  • 1,898
  • 1
  • 12
  • 25
  • 1
    The short answer is 'no'. The long answer is - MCVE, please. – SergeyA Oct 26 '18 at 19:57
  • If you're not doing anything silly and you include your dependencies correctly in each header, then the include order shouldn't matter. But to make this question answerable, what is the error exactly, and what does the header file look like? I would suspect you're `using namespace std;` [which is bad](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) to be causing a naming conflict but you should show some code to be sure – alter_igel Oct 26 '18 at 19:59
  • To be clear, MVCE refers to a [Minimum, Complete, Verifiable Example](https://stackoverflow.com/help/mcve) which would help make your question answerable, and which has the benefit of likely finding the bug for you. Please [edit](https://stackoverflow.com/posts/53015503/edit) your question to include one. – alter_igel Oct 26 '18 at 20:02
  • 2
    My rule of thumb is standard headers first, followed by library headers, followed by my own headers. This makes finding errors from my own headers easier. This isn't required though. – NathanOliver Oct 26 '18 at 20:03
  • @NathanOliver always always always the other way around! – SergeyA Oct 26 '18 at 20:04
  • Sounds like there is something bad in one of your quoted headers. – Galik Oct 26 '18 at 20:06
  • Sorry. I just updated the OP with the files causing this error. – 24n8 Oct 26 '18 at 20:06
  • `_UTILITIES_H` is not the most unique of names. Also IIRC it may cause undefined behavior because it begins with `_` followed by a capital letter (unlikely to be the problem in real life). – Galik Oct 26 '18 at 20:08
  • 4
    "`#ifndef _UTILITIES_H`" - Bad name for a header guard. Any name starting with underscore and followed by a capital letter is *reserved for the implementation* and you are not allowed to use it. Also; it's unlikely to be unique. See https://stackoverflow.com/questions/49688518/how-to-properly-name-include-guards-in-c/49688652 – Jesper Juhl Oct 26 '18 at 20:10
  • I swapped the include guards for this and got the following errors: `g++ -g -Wall -c utilities.cpp utilities.cpp: In function ‘double calcNorm(std::vector)’: utilities.cpp:5:8: error: redefinition of ‘double calcNorm(std::vector)’ double calcNorm(std::vector array) //template? ^ utilities.h:3:8: note: ‘double calcNorm(std::vector)’ previously defined here #pragma once ^ makefile:12: recipe for target 'utilities.o' failed make: *** [utilities.o] Error 1` – 24n8 Oct 26 '18 at 20:11
  • I am pretty sure this is not complete MCVE. Order of includes or bad name for include guards can't produce the error as reported. – SergeyA Oct 26 '18 at 20:13
  • 2
    @NathanOliver I use the opposite convention: own headers first. Curiously enough, my reasoning is exactly the same as yours. – eerorika Oct 26 '18 at 20:13
  • And I also changed the header guard name, and that didn't fix the issue either. – 24n8 Oct 26 '18 at 20:14
  • Hmmm. I think I found the issue. I had this binary file called `utilities.h.gch` (not sure where it came from) in the directory. I removed it and the compiler issue went away. – 24n8 Oct 26 '18 at 20:16
  • @user2079303 and SergeyA. I guess I shouldn't have been so general. In an implementation file for a header file I do the reverse of what I said to find if the header file has an missing dependencies. In my main file I do it the way I stated so I don't have to worry about my includes making me thing there is an error in the standard include files. – NathanOliver Oct 26 '18 at 20:16
  • @SergeyA Totally agree. I put my header includes *first* (unless i'm using a PCH environment, where obviously the PCH goes first, but I never enable that until toward the end of the project), then library headers. That ensures you don't build a .h that implicitly depends on other headers pulled in from the including .cpp file. – WhozCraig Oct 26 '18 at 20:17
  • @NathanOliver *I* prefer: My own headers first, then library headers, then standard headers. This ensures that my own header files are self contained and don't depend on transitive includes. – Jesper Juhl Oct 26 '18 at 20:21

4 Answers4

4

When compiling a C++ source file, if you have multiple headers consisting of bracketed and quoted headers, do the bracketed headers have to always be listed first?

No.

Header files (within source files, as well as within other header files) can be in any order. In fact, no header file even needs to be included at the beginning of the source file as long as each header file is before any declarations that depend on declarations from the header. Whether the path was specified using angle brackets or using double quote is irrelevant in this regard.

Technically, a header can be written in a way that would force other headers to be included before it, but that's in general a bad code smell and most often a bug.


An exception to this is pre-compiled header which is a non-standard feature implemented by some compilers. The pre-compiled header must be before any declaration (and thus any other include) of the source file.

Hmmm. I think I found the issue. I had this binary file called utilities.h.gch (not sure where it came from) in the directory. I removed it and the compiler issue went away.

Ah. gch is a file extension used by pre-compiled headers, and this explains why your example wasn't sufficient to reproduce your problem. For more details about how pre-compiled headers behave, see the manual of your compiler.

eerorika
  • 232,697
  • 12
  • 197
  • 326
1

"do the bracketed headers have to always be listed first" - No.

It has nothing to do with the order of the includes and everything to do with the rules for how includes are searched for. An include statement like #include "foo.h" will cause the preprocessor to first look in the current directory of the source file, then in whatever include paths you've provided (and the default ones). An include statement like #include <foo.h> will do the same except that it will skip the initial "look in the current directory" step.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
1

No. The only difference between headers enclosed in angle brackets and headers enclosed in quotes is where the system will look for them. (Note that standard headers may not exist as separate files at all; that's an implementation detail that you don't need to worry about.)

Tim Randall
  • 4,040
  • 1
  • 17
  • 39
0

Short answer: No.

Long answer: The #include directive almost literally pastes the contents of that file into the source. A header must be included before any of its functionality is used. Period. If you include iostream at the end but you don't use that header, there will be no problem

DarkAtom
  • 2,589
  • 1
  • 11
  • 27