Is it bad to use macros such as __LINE__ or __DATE__?

Started by
10 comments, last by nfries88 8 years, 1 month ago

As the title says I would like to know if it's bad to use macros such as :

  • __FILE__
  • __LINE__
  • __DATE__
  • __TIME__

Why am I asking this?

Because I don't see many applications using it, instead it uses some kind of library to do this instead.

Is there any reason to why they choose a library over macros?

Advertisement

There is no library which could provide this information. You could only get that functionality with a custom preprocessing step before passing the source to the compiler (which would be just a hand-rolled kind preprocessor definition again).

As BitMaster says.

Which leads me to ask: What do you think these macros do exactly? I feel there is some confusion here.

Those macros are just used for testing and debugging, and not really useful for the actual application. (why would an end user be interested in what line in a source code file a printout happened at, or when the app was compiled?)

Absolutely not a bad idea to use them, if you feel you need to embed that information to help you track down errors.

Just make sure all the compilers you want to use to compile the source code support the ones you use.

I don't see a valid reason to say it's bad practice.

I think almost every C/C++ compiler support any of those macros. I can't not say the same of __FUNCTION__

As BitMaster says.

Which leads me to ask: What do you think these macros do exactly? I feel there is some confusion here.

Those macros are just used for testing and debugging, and not really useful for the actual application. (why would an end user be interested in what line in a source code file a printout happened at, or when the app was compiled?)

Absolutely not a bad idea to use them, if you feel you need to embed that information to help you track down errors.

Just make sure all the compilers you want to use to compile the source code support the ones you use.

To example unity uses a structure which contains date.

(System.DateTime)

And for __LINE__ / __FILE__ I just wanted to know if it had some bad impacts on the application. :P

As BitMaster says.

Which leads me to ask: What do you think these macros do exactly? I feel there is some confusion here.

Those macros are just used for testing and debugging, and not really useful for the actual application. (why would an end user be interested in what line in a source code file a printout happened at, or when the app was compiled?)

Absolutely not a bad idea to use them, if you feel you need to embed that information to help you track down errors.

Just make sure all the compilers you want to use to compile the source code support the ones you use.

To example unity uses a structure which contains date.

(System.DateTime)

And for __LINE__ / __FILE__ I just wanted to know if it had some bad impacts on the application. :P

System.DateTime represents a time. __DATE__ is the build date and __TIME__ is the build time. Values defined in compile time.

__DATE__ is the build date and __TIME__ is the build time. Values defined in compile time.
This. More precisely, they are the date and time of preprocessing the current translation unit.

What's bad about those macros apart from them being ugly all-upercase? They can be deceptive.

For example, you might expect __FILE__ inside a header to show the header's name. That's "intuitive", but it's not what you get. It shows the name of the translation unit. You might expect "name" to mean "name", not "path", but under GCC it really means "path". Per the standard, it means "presumed name" whatever presumed is supposed to mean. You might expect that __FILE__ is a constant expression, seeing how the standard says it is a literal. It's not, at least not with GCC. Nor is __func__ or __FUNCTION__.

You might expect that __TIME__ is,, well, the time when your executable is built. Or something. It is however the time when a particular translation unit is preprocessed. Which means that __TIME__ may very well be different if it appears twice in two source files. The standard does not guarantee that two instances of __TIME__ within the same translation unit are even the same (they probably are since anything different would be kind of nonsensical, but it's not guaranteed). It is allowable to provide an implementation-defined value, too, if the implementation can't be bothered to determine the current time. Surprise, you didn't see that coming, did you?

__LINE__ is the presumed (whatever that means) line number in the current source file. What's __LINE__ if you use it in an included header? You tell me?

__DATE__ is the build date and __TIME__ is the build time. Values defined in compile time.
This. More precisely, they are the date and time of preprocessing the current translation unit.

What's bad about those macros apart from them being ugly all-upercase? They can be deceptive.

For example, you might expect __FILE__ inside a header to show the header's name. That's "intuitive", but it's not what you get. It shows the name of the translation unit. You might expect "name" to mean "name", not "path", but under GCC it really means "path". Per the standard, it means "presumed name" whatever presumed is supposed to mean. You might expect that __FILE__ is a constant expression, seeing how the standard says it is a literal. It's not, at least not with GCC. Nor is __func__ or __FUNCTION__.

You might expect that __TIME__ is,, well, the time when your executable is built. Or something. It is however the time when a particular translation unit is preprocessed. Which means that __TIME__ may very well be different if it appears twice in two source files. The standard does not guarantee that two instances of __TIME__ within the same translation unit are even the same (they probably are since anything different would be kind of nonsensical, but it's not guaranteed). It is allowable to provide an implementation-defined value, too, if the implementation can't be bothered to determine the current time. Surprise, you didn't see that coming, did you?

__LINE__ is the presumed (whatever that means) line number in the current source file. What's __LINE__ if you use it in an included header? You tell me?

Oh, I thought that __TIME__ was the current system time. lol :3

Makes sense now though, at least mos too it.

__DATE__ and __TIME__ can make trouble if you need bit-by-bit reproducable builds. I would assume that is not true for games, but I've been working on projects where that was a hard requirement.

Typical use is a macro like


#define NOT_REACHED() reached_nonreachable(__FILE__, __LINE__)

void reached_nonreachable(const char *fname, int line) {
    fprintf(stderr, "Breach in the time-continuum! reached a NOT_REACHED statement (at %s, line %d)\n", fname, line);
    exit(1);
}

which you use in spots where you don't expect to ever arrive:


switch (bool_value) {
    case 0: ...  break;
    case 1: ...  break;
    default: NOT_REACHED();
}

Computers manage to reach such spots more often than you'd want :P

This topic is closed to new replies.

Advertisement