Discussion:
General Preference in C++
Add Reply
Jack
2024-08-21 01:30:54 UTC
Reply
Permalink
Do you guys have any preference in C++ to use something like this:

constexpr size_t N = 12;
#define N 12

constexpr is modern way of doing things but in terms of efficiency what
is the best way to do?

You can then define an array like so:

double numbers[N] {0};

I wonder if you guys have anything to say about this.
Keith Thompson
2024-08-21 01:53:28 UTC
Reply
Permalink
Post by Jack
constexpr size_t N = 12;
#define N 12
The first N is of type size_t. The second is of type int (the type of
the literal 12).
Post by Jack
constexpr is modern way of doing things but in terms of efficiency what
is the best way to do?
There is unlikely to be any difference in efficiency.
Post by Jack
double numbers[N] {0};
I wonder if you guys have anything to say about this.
I believe the general consensus (and my own preference) is to use core
language features rather than macros unless there's a very good reason
to use a macro.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+***@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
Chris Ahlstrom
2024-08-22 17:18:09 UTC
Reply
Permalink
<brevsnip>
I believe the general consensus (and my own preference) is to use core
language features rather than macros unless there's a very good reason
to use a macro.
I use macros for enabling/disabling code depending on developer preference or
platform.

Is that a sensible use of macros? (A little off-topic, sorry).
--
My only love sprung from my only hate!
Too early seen unknown, and known too late!
-- William Shakespeare, "Romeo and Juliet"
Scott Lurndal
2024-08-22 17:54:38 UTC
Reply
Permalink
Post by Chris Ahlstrom
<brevsnip>
I believe the general consensus (and my own preference) is to use core
language features rather than macros unless there's a very good reason
to use a macro.
I use macros for enabling/disabling code depending on developer preference or
platform.
Is that a sensible use of macros? (A little off-topic, sorry).
Generally speaking, that's sensible.

However it can be taken to an extreme that makes maintenance of
the application more complicated. Every conditional used to
select optional code needs to be tested combinitorially to ensure
proper operation of the application, which can consume considerable
QA time. If N is the number of macros, then there are as many
as 2^n (or more for non-boolean conditionals) different compiles
required for full verification of the application (just to ensure
that it compiles sucessfully).

Maintenance can be very difficult when there are an excessive number of
conditionally compiled segments in a codebase.
Bonita Montero
2024-08-22 18:08:19 UTC
Reply
Permalink
Post by Scott Lurndal
Post by Chris Ahlstrom
<brevsnip>
I believe the general consensus (and my own preference) is to use core
language features rather than macros unless there's a very good reason
to use a macro.
I use macros for enabling/disabling code depending on developer preference or
platform.
Is that a sensible use of macros? (A little off-topic, sorry).
Generally speaking, that's sensible.
However it can be taken to an extreme that makes maintenance of
the application more complicated. Every conditional used to
select optional code needs to be tested combinitorially to ensure
proper operation of the application, which can consume considerable
QA time. If N is the number of macros, then there are as many
as 2^n (or more for non-boolean conditionals) different compiles
required for full verification of the application (just to ensure
that it compiles sucessfully).
lol
Post by Scott Lurndal
Maintenance can be very difficult when there are an excessive number of
conditionally compiled segments in a codebase.
David Brown
2024-08-23 07:08:18 UTC
Reply
Permalink
Post by Scott Lurndal
Post by Chris Ahlstrom
<brevsnip>
I believe the general consensus (and my own preference) is to use core
language features rather than macros unless there's a very good reason
to use a macro.
I use macros for enabling/disabling code depending on developer preference or
platform.
Is that a sensible use of macros? (A little off-topic, sorry).
Generally speaking, that's sensible.
However it can be taken to an extreme that makes maintenance of
the application more complicated. Every conditional used to
select optional code needs to be tested combinitorially to ensure
proper operation of the application, which can consume considerable
QA time. If N is the number of macros, then there are as many
as 2^n (or more for non-boolean conditionals) different compiles
required for full verification of the application (just to ensure
that it compiles sucessfully).
Maintenance can be very difficult when there are an excessive number of
conditionally compiled segments in a codebase.
Usually the number of valid combinations is not nearly that many, as
they are rarely independent. (And if they are truly independent, then
they can often be tested independently.) But you are right that too
many of them can make code hard to handle in many aspects.
Chris Ahlstrom
2024-08-23 13:41:30 UTC
Reply
Permalink
Post by David Brown
Post by Scott Lurndal
Post by Chris Ahlstrom
<brevsnip>
I believe the general consensus (and my own preference) is to use core
language features rather than macros unless there's a very good reason
to use a macro.
I use macros for enabling/disabling code depending on developer preference or
platform.
Is that a sensible use of macros? (A little off-topic, sorry).
Generally speaking, that's sensible.
However it can be taken to an extreme that makes maintenance of
the application more complicated. Every conditional used to
select optional code needs to be tested combinitorially to ensure
proper operation of the application, which can consume considerable
QA time. If N is the number of macros, then there are as many
as 2^n (or more for non-boolean conditionals) different compiles
required for full verification of the application (just to ensure
that it compiles sucessfully).
Maintenance can be very difficult when there are an excessive number of
conditionally compiled segments in a codebase.
Usually the number of valid combinations is not nearly that many, as
they are rarely independent. (And if they are truly independent, then
they can often be tested independently.) But you are right that too
many of them can make code hard to handle in many aspects.
Thanks for the responses. Periodically I go through the code and look at the
macros to find ways to get rid of them.

- Making the feature permanent
- Removing the feature entirely
- Off-loading/hiding the feature choices in a function
--
Civilization is the limitless multiplication of unnecessary necessities.
-- Mark Twain
Andrey Tarasevich
2024-08-21 03:07:42 UTC
Reply
Permalink
Post by Jack
constexpr size_t N = 12;
#define N 12
constexpr is modern way of doing things but in terms of efficiency what
is the best way to do?
There's no difference in efficiency.

One can probably come up with a few reasons to prefer a macro for this
purpose, like

1. Compatibility with C in cross-compiled header files
2. Ability to use a named constant in subsequent preprocessor directives
(e.g. `#if`)
3. Probably something else...

But these reasons are focused rather narrowly of some niche
applications. When you _have_ a choice, there's no reason to avoid
`constexpr`.
--
Best regards,
Andry
David Brown
2024-08-21 07:07:52 UTC
Reply
Permalink
Post by Andrey Tarasevich
Post by Jack
constexpr size_t N = 12;
#define N 12
constexpr is modern way of doing things but in terms of efficiency what
is the best way to do?
There's no difference in efficiency.
One can probably come up with a few reasons to prefer a macro for this
purpose, like
1. Compatibility with C in cross-compiled header files
"enum { N = 12 };" also works if you need compatibility with C in
headers. And if you are on C23, then "constexpr size_t N = 12;" is fine
in C too.

You can also write "static const size_t N = 12;" and use it in a fair
number of circumstances, though not as many as with a constexpr or
macro. You can use it for local variable array sizes in C and C++, but
not for a file-scope array in C.
Post by Andrey Tarasevich
2. Ability to use a named constant in subsequent preprocessor directives
(e.g. `#if`)
"if constexpr" and templates can provide alternatives to using #if, and
work with constexpr values. But conditional preprocessor may be simpler
and clearer, depending on the context and usage.
Post by Andrey Tarasevich
3. Probably something else...
Two things come to mind for "#define N 12" :

3a. You can later on write :

#undef N
#define N 42

3b. You can write :

#ifndef N
#define N 100
#endif

These make #define's nice for things like configuration files where you
might have defaults that you want to override. Template variables,
including template constexpr variables, can be an alternative.
Post by Andrey Tarasevich
But these reasons are focused rather narrowly of some niche
applications. When you _have_ a choice, there's no reason to avoid
`constexpr`.
Agreed. A key point is that constexpr variables (like other variables)
follow scoping rules, and can be put in namespaces or inside classes.
Bonita Montero
2024-08-22 09:33:51 UTC
Reply
Permalink
Post by Jack
constexpr size_t N = 12;
#define N 12
I prefer constexpr / static constexpr (membe) because it can be scoped.
Post by Jack
constexpr is modern way of doing things but in terms of efficiency what
is the best way to do?
double numbers[N] {0};
I wonder if you guys have anything to say about this.
Loading...