Lee Yi
Lee Yi

Reputation: 527

Custom error function C++

Is there a way to get the line the code is being executed on?

For example:

int death() {
  cout << "An error has occurred on line " << line << endl;
  exit(128);
}

Then if I call death() function on line 64 it tells me that the error occurred on line 64.

EDIT: Most people seem to be telling me to use the __LINE__ macro. I know you can do that:

#define DEATH(message) death(__LINE__, message)

where

int death(int line, string message) {
  cout << "An error has occurred at line << line << endl;
}

But I'm thinking of using it in such a way:

string readFile(string file) {
  string str;
  ifstream stream(file);
  if (!stream) { death(); } //if this is line 23, it prints line 23
  stream >> str;
  stream.close();
  return str;
}

//instead of printing line 64 if readFile() is executed on line 64

And using the __LINE__ macro alone only returns the line at which the death() function was executed. In other words, if I execute readFile() at line 64, I want death() to print line 64, not the line at which it was defined inside the readFile() function.

Upvotes: 1

Views: 632

Answers (4)

GoBusto
GoBusto

Reputation: 4778

Try using the __LINE__ macro:

The standard predefined macros are specified by the relevant language standards, so they are available with all compilers that implement those standards. Older compilers may not provide all of them. Their names all start with double underscores.

__FILE__

This macro expands to the name of the current input file, in the form of a C string constant. This is the path by which the preprocessor opened the file, not the short name specified in #include or as the input file name argument. For example, /usr/local/include/myheader.h is a possible expansion of this macro.

__LINE__

This macro expands to the current input line number, in the form of a decimal integer constant. While we call it a predefined macro, it's a pretty strange macro, since its "definition" changes with each new line of source code.

__FILE__ and __LINE__ are useful in generating an error message to report an inconsistency detected by the program; the message can state the source line at which the inconsistency was detected.

If you want to get a line number other than the current line, you'll need to store the line number from __LINE__ at an earlier point. For example, this code gets the first line number of the function that calls death():

#include <stdio.h>
#include <stdlib.h>

/* Set up some stuff to keep track of where you died. */
int DEATH_LINE = 0;
#define CAN_DIE DEATH_LINE = __LINE__;
void death() { printf("OH NO, YOU DIED AT LINE %d!\n", DEATH_LINE); }

/* This function can die, so get the first line number using CAN_DIE */
int someFunction() { CAN_DIE
  printf("Hello, World!\n");
  death();
  printf("Goodbye, Cruel World!\n");
  return 0;
}

int main() { return someFunction(); }

This produces the following output:

Hello, World!
OH NO, YOU DIED AT LINE 10!
Goodbye, Cruel World!

Process returned 0 (0x0)   execution time : 0.009 s
Press any key to continue.

Alternatively, you could get the line number that calls the function as follows:

#include <stdio.h>
#include <stdlib.h>

int DEATH_LINE = 0;
#define CAN_DIE(x) ((DEATH_LINE = __LINE__), (x));
void death() { printf("OH NO, YOU DIED AT LINE %d!\n", DEATH_LINE); }

int someFunction() {
  printf("Hello, World!\n");
  death();
  printf("Goodbye, Cruel World!\n");
  return 123;
}

int main() { return CAN_DIE(someFunction()); }

This produces the following output:

Hello, World!
OH NO, YOU DIED AT LINE 15!
Goodbye, Cruel World!

Process returned 123 (0x7B)   execution time : 0.008 s
Press any key to continue.

Note that the second example requires the calling function to wrap the other function (i.e. the one that actually calls death()) in a macro to set the current line number correctly.

Upvotes: 2

fxam
fxam

Reputation: 3982

Use __LINE__

void foo() {
  if (somethingWrong) { death(__LINE__); } // Pass this line number to death()
}

void death(int line) {
  cout << "An error has occurred on line " << line << endl;
}

Upvotes: 0

Sadique
Sadique

Reputation: 22821

You can use __LINE__.

The __LINE__ macro is often combined with the __FILE__ macro, which expands to the current file name.

#define ERR(msg) printf("%s : %d", (msg), __LINE__)

const char * msg ="An error has occurred on line ";
cout << ERR(msg) << endl;

Get code line with LINE

Upvotes: 1

You need to mix macro and functions:

int death_at(int line) {
   cerr << "An error has occurred on line " << line << endl;
}
#define DEATH() death_at(__LINE__)

You might even have

#define FAILURE(Out) do { cerr << __FILE__ << ":" __LINE__ \
                          << ": " << Out << endl; } while(0)

then you could code:

FAILURE("x is " << x)

And you might even use some throw near the end of your FAILURE macro definition.

Upvotes: 1

Related Questions