I have written some code that contains a system to report error messages to error log file. I use a class structure to do this. However, some parts of the code contain functions that I think might be useful in a more generic context. So, I am trying to use preprocessor directives to redefine the class structure for those more generic instances when I will not want to use and error log file. Here is what I have come up with. . .

#ifdef USES_ERROR_HANDLER_H
#include "ErrorHandler.h"
#else
class InternalErrorReport
 {
  private:
   string logfilename;
  public:
   void ProgramExit() const
     {
       cout << "\nAbnormal Program Exit.\n\n";
       exit(9);
     };

   void report (const std::string& line) const
     {
       cout << line;
     };

   void report (const double& v) const
     {
       cout << v;
     };

 };
InternalErrorReport Log;

#endif

I use #define USES_ERROR_HANDLER_H in the main program code, and the header file Error_Handler.h contains the original error class and error reporting functions. Everything works fine if I use #include "Error_Handler.h" in the code.

Right now I am trying to get this to complie with USES_ERROR_HANDLER.H defined. So, everything should work like it worked before. However, when I use the code listed above I get a compiler error .. for code later on in the program that normally works fine. Since the code above is the only new code, the error has to be there. But where?

Any insights will be appreciated.

Recommended Answers

All 6 Replies

It would be helpful to see the compiler error.

The compiler error highlights a line of code much latter in the program and states:

) expected.

That is the compiler error message. This compiler error is not very helpful and does not always indicate that there are unbalanced parentheses. Note, that if I comment out every line listed above except for this one:

include "ErrorHandler.h"

The file compiles and runs just fine. So balancing parentheses is not really the problem here. When I've run in to this compiler error before it can frequently be resolved by adding std:: to variable declarations. But, when USES_ERROR_HANDLER_H is defined the preprocessor should just include "ErrorHandler.h" and ignore everything else. So even if I have an error in the class related code is should not be relevant because the preprocessor should skip over it. But that is not what is happening.

Everything works fine if I use #include "Error_Handler.h" in the code.

But

#include "ErrorHandler.h"

Typo in post or actual mistake?

That said it would still help to see a few lines of code round the line producing the error. Also is this the first compiler error you get, if not what is the first one, remember it is always possible that subsequent compiler errors after the first one are just an artifact of the first error reported.

Ok. Here is the code down to the line where the "error" occurs.

#ifndef Matrix_H
#define Matrix_H

#include "MathValues.h"

#ifdef USES_ERROR_HANDLER_H
#include "ErrorHandler.h"
#else
class InternalErrorReport
{
  private:
     string logfilename;
  public:
    void ProgramExit() const
     {
      cout << "\nAbnormal Program Exit.\n\n";
      exit(9);
      };
  void report (const std::string& line) const
     {
      cout << line;
     };
  void report (const double& v) const
    {
     cout << v;
    };
};
InternalErrorReport Log;
#endif

#pragma warn -inl
using namespace std;


// used to specify referent axes
const char X='X';
const char Y='Y';
const char Z='Z';
const int x=0; // x data row of a matrix
const int y=1; // y data row of a matrix
const int z=2; // z data row of a matrix


class Matrix;

// ********  VECTOR CLASS AND FUNCTIONS
class Vector
 {
  private:
    double *v; //data
    int L;
  public:
   Vector (): v(new double[1]), L(1){ };                                        // default constructor
   Vector (int n): v(new double[n]), L(n) { }                                   // constructor
   ~Vector() {delete[] v; };                                                    // destructor
   double& operator() (const int n) {return v[n];}                              //output a value from [cell]
   double& operator() (const int n) const  {return v[n];}
   Vector(const Vector& u): v(new double[u.L]), L(u.L)                          //copy constructor
       {for (int i=0; i<L; i++) v[i]=u(i); }

   int length () const {return L;};
   void set (const int n) {L=n; v=new double[n];}
   void dump() const;
   void dump(fstream &fout) const;

Yes, I am aware that multiple compiler error can result from just one. I am reporting the first compiler error. You can see that there are no unbalanced parenthesis here.

What I have learned in the interim is that while USES_ERROR_HANDLER_H is defined in another part of my program, that fact that it is defined is not being carried over into this header file. Of course, that should mean that the complier loads ErrorHandler.h and ignores the rest of the code within the preprocessor #else. But that is not what is happening. The mere presence of these preprocessor lines are preventing the file from compiling. However, if I add the line #define USES_ERROR_HANDLER_H in the very top of this file, everything compiles.

What I do not understand why my a #define does not carry through to the different parts of the program. I #define USES_ERROR_HANDLER_H in the file that contains the main() function. Shouldn't that defintion carry over to all the other files within the project? Isn't that the whole point of using the define preprocessor around the contents of a header file, so that multiple copies of the header contents do not get incorporated within the code? But if the #define preprocessor is not carrying is definintions across the different files within the project then the whole concept falls apart.

C compilers process one file at a time, why would you expect that a definition in one is necessarily available in another? Include guards are there to prevent multiple definitions in the case that somewhere in the current file's include tree a file gets included twice.

You can set a macro definition as a compiler flag to ensure that it is present throughout your program (in gcc that looks like -DFLAG_TO_SET).

If you want to see what the pre-processor step produces you can simply run just that stage of compilation. For example, on *nix platforms you can run cpp file. It is an interesting exercize to do that - just so you better understand the process.

I knew my problem was in my understand of the preprocessor process.

What you have stated here clarified where I was misunderstanding things and thus helped me to understand what was going wrong.

Thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.