-2

Can I set default arguments to a #defined value?

#define WIDTH 1920
#define HEIGHT 1080

void calculate(int width = WIDTH, int height = HEIGHT) {
    //do stuff
}
icanfathom
  • 291
  • 4
  • 11

3 Answers3

1

You can use #define. But should you?

#define ignores scope, and has other problems. This code will work just as well, without making anyone gasp in horror at unnecessary defines.

enum {WIDTH  = 1920 };
enum {HEIGHT = 1080 };

void calculate(int width = WIDTH, int height = HEIGHT) 
{
  //do stuff
}

This will also work:

const int WIDTH  = 1920;
const int HEIGHT = 1080;

void calculate(int width = WIDTH, int height = HEIGHT) 
{
  //do stuff
}

As will this, though it's not as clear:

void calculate(int width = 1920, int height = 1080) 
{
  //do stuff
}
Community
  • 1
  • 1
Topological Sort
  • 2,733
  • 2
  • 27
  • 54
  • 1
    If it is not macro anymore why to keep it UPPERCASE? – Slava Sep 20 '16 at 18:06
  • Because it is conventional to put consts in upper case -- makes it easy to see what's const. http://stackoverflow.com/questions/838929/naming-why-should-named-constants-be-all-uppercase-in-c-java There is some controversy on this. – Topological Sort Sep 20 '16 at 18:08
  • 1
    It is not conventional, it is a bad habit that grows from defining constants as preprocessor macros. And exactly for the same reason. – Slava Sep 20 '16 at 18:10
  • Any reason why you'd want to make it an enum? – Caramiriel Sep 20 '16 at 18:27
  • Using an enum rather than a const has these advantages: it's a little less typing; it can go into a .h file without having to use extern and do the initialization in a .cc or .cpp file; it takes up less memory at runtime (a trivial concern to be sure); if it's a class member, you won't have to initialize it in the .cc or .cpp file (as in `int MyClass::myConst_ = 0;`) if using an earlier compiler. For me, the first two reasons matter most. – Topological Sort Sep 21 '16 at 14:46
  • 1
    The convention of using ALL CAPS for constants doesn't come from C++ preprocessor macros, but from ALGOL (which predates C), where it was used for constants. It's also used in Pascal, Ruby, PHP, and other languages. Good or bad, it is an intentional convention in many languages. – Topological Sort Sep 22 '16 at 20:53
0

Yes. The WIDTH and HEIGHT macros will just expand to 1920 and 1080. This will do the same as :

void calculate(int width = 1920, int height = 1080) { // ...

Depending on your case, you may prefer static const int over macros for different reasons, which you can find on this answer; or at least rename WIDTH and HEIGHT to something more specific, because this seems very conflict-prone. As stated by the other answer, one advantage to using static variables is that they are scoped.

C++17 note : You will be able to inline a variable. If the compiler doesn't/can't do this already over consts during the optimisation stage, you may prefer this approach in the future.

Community
  • 1
  • 1
asu
  • 1,875
  • 17
  • 27
0

Yes you can, but dont do it if you can avoid it. Imagine you have the defines in a header

// foo.h
#define WIDTH 123

and for some reason you include this header in some other header containing something like the following:

// bar.h
#include "foo.h"
int bar(int WIDTH) { return WIDTH*2; }

To my experience this can lead to very nasty bugs, that can be avoided completely if you simply dont use macros.

You might argue that the capitalization saves you from such mistakes, however then you still could have

// moo.h
#define WIDTH 321
#include "foo.h"

This wont even lead to a compiler error, but even harder to trace bugs.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185