Re: static constexpr
On Friday, 17 October 2014 10:31:04 UTC+3, glen stark wrote:
Hello everyone.
I recently ran into the following in a unit test file:
static constexpr int maxval = 12345;
/// more of the same...
Essentially the author is using constexpr the same way one might have
used a macro definition in the past. It gets used within scope of the
single file to do things like initialize an array. So far so good.
I'm confused by the use of static here though. In my pedestrian
knowledge of how static and constexpr work, I think the use of static is=
superfluous here.
I looked at a couple stack-overflow answers (http://stackoverflow.com/
questions/26152096/when-and-why-would-you-use-static-with-constexpr
and
http://stackoverflow.com/questions/13865842/does-static-constexpr-
variable-make-sense
)
but I have to admit to remaining unclear. As far as I can see, my
pedestrian knowledge gives me the right answer: If the same object
should be used over all instances of a class (for example), static is
used to provide this. But for a constexpr of an object or basic data
type, whose scope is global over a file, it's completely redundant. Is=
that correct?
I appreciate any clarification on this issue.
First the legal side. Variable that is explicitly declared 'const' or
'constexpr' in namespace scope is implicitly with internal linkage. C++
does not forbid to restate it explicitly by using 'static' keyword.
IOW 'static' is redundant but not forbidden legally.
Then style side. Some may make usage of keyword 'static' together
with 'constexpr' in namespace scope an issue of style. If they do
they go usually extreme ... they either demand or forbid it.
Lot of programmers do not care about standard so much but are
ready to fight for style. So ... see around with whom you work
together.
Further I add some redundant information that may shed light to
how 'const', 'constexpr' and 'extern' can be coupled. You did not ask
it but it may be worth to think through while you already are
pondering about 'constexpr'.
Generally we may sometimes want to use something that is
'constexpr' (compile-time constant) also as run-time immutable
variable with external linkage. For example we may care about
address of that variable and want it to be same globally so others
can compare it for equality. Also it may be of class type. Also we
may want to have different levels of visibility of types and variables
for different levels of encapsulating and compiler fire-walling.
Given that and by intent expressed in standard of C++11 it is
AFAIK legal to write such a code for practical purposes:
// Imagine that all below is #included together
// forward declaration of type
class Tricky;
// ... we may use opaque type Tricky
// in several ways here ...
// ... declare functions
Tricky const& trickyAddress();
// ... declare variables
extern const Tricky g_tricky;
// ... we may use address of or reference to
// g_tricky in several ways here ...
Tricky const& trickyAddress() { /* on some cases */ return g_tricky; }
// actual definition of the type Tricky
// Note: despite I changed 'class' to 'struct' the compilers
// may warn but must compile it
struct Tricky { /* stuff1 */ };
// ... here we may use Tricky as fully known complete type and
// g_tricky as global immutable variable of that type ...
// I omit examples
// actual definition of g_tricky
// Note: I changed 'const' to 'constexpr' and compilers must
// accept it
constexpr Tricky g_tricky { /* stuff2 */ };
// here we can use g_tricky as compile-time constant
So may be it clarifies something to you ... or not? ;)