1

novice C++ programmer here.

I'm using Numerical Recipes (V3) source code as part of a larger, modulated C++ project.

While I'll try not to get into the specifics of my problem, I am curious as to why these NR header files do not incorporate any header guards? I'm aware this question is very specific to those who have used this code in the past, but looking at the NR forums they seem quite inactive...

The errors I'm finding with my code that prompted this question are;

error LNK2005: "void __cdecl gaussj(class NRmatrix &)" (?gaussj@@YAXAAV?$NRmatrix@N@@@Z) already defined in Schmidt_V2_(Zeta).obj

error LNK2005: "void __cdecl gaussj(class NRmatrix &,class NRmatrix &)" (?gaussj@@YAXAAV?$NRmatrix@N@@0@Z) already defined in Schmidt_V2_(Zeta).obj

pokl90
  • 21
  • 4
  • 3
    The Numberical Recipes code isn't of the highest quality and that is an understatement. I also believe there are severe restrictions on code reuse. – rubenvb Feb 18 '16 at 16:30
  • 1
    It's because they are very naughty. Their insistence on 1-basing arrays (due to Fortran port) is particularly galling. But the code is tried and tested, so worth using, sometimes. – Bathsheba Feb 18 '16 at 16:30
  • Except for being well debugged in the numerical parts, Numerical Recipies in * code is basically an example of how *not* to write code. – Ami Tavory Feb 18 '16 at 16:35
  • It would seem to me that only the authors of the code in NR could answer the question as currently asked, and unless they are active on SO and chime in, we can only speculate as to their motivations. This would make this "opinion based", which is a common reason for closing questions. – njuffa Feb 18 '16 at 16:44

1 Answers1

2

AFAIK there is no good reason. There are a few situations where you might legitimately want not to use an include guard (see this question), but this isn't one of them.

If you need to include those headers from several places in your project, you must introduce your own guards, like so:

#include <a_normal_thing>
#include <another_normal_thing>

#ifndef SPECIAL_NONESENSE_H
#define SPECIAL_NONESENSE_H
#include <special_nonsense>
#endif

// More normal includes...

This is verbose and annoying, but it'll work.

EDIT: Or nowadays, it's pretty safe to use #pragma once as Donnie suggests in a comment below. This won't work in versions of GCC older than 3.4, but probably you don't need to support that anymore.

Community
  • 1
  • 1
David Seiler
  • 9,557
  • 2
  • 31
  • 39
  • 1
    Or you could just go back and put `#pragma once` in the top of the header. It doesn't matter if someone else wrote it or not, you can still change your copy. – Donnie Feb 18 '16 at 16:55