Meaning of terms "subexpression" and "constant expression"
Consider the following example:
#include <iostream>
template <void (*pf)()>
struct X
{
template <void (*)()>
struct Y;
static void instantiate() { (void)m; }
typedef Y<&X::instantiate> Inst;
X() { pf(); }
static X m;
};
template <void (*pf)()>
X<pf> X<pf>::m;
void f()
{
std::cout << "f()\n";
}
int main()
{
sizeof X<&f>();
}
According to N3225 - 3.2/2,
An expression is potentially evaluated unless it is an unevaluated
operand (Clause 5) or a subexpression thereof.
Can the expression f in sizeof X<&f>() be considered as subexpression
of X<&f>()? Is the expression f potentially evaluated and is the
function f odr-used?
Another example:
int main()
{
int m = 11;
int n = 22;
sizeof(new char[m]); // (1)
sizeof(new char[m][n]); // (2)
}
According to N3225 - 5.19/2,
A conditional-expression is a constant expression unless it involves
one of the following as a potentially evaluated subexpression (3.2)
[...]
Does this rule imply that
at (1) new char[m] and m are constant expressions,
at (2) new char[m][n], m, and even n are constant expressions?
5.19/2 also contains the following wording:
an invocation of an undefined constexpr function or an undefined
constexpr constructor outside the definition of a constexpr function
or a constexpr constructor
Where exactly a constexpr function shall be considered defined?
struct X
{
static constexpr int size()
{
return sizeof(X);
}
char arr[size()]; // is 'size' undefined here?
};
struct Y
{
static constexpr int offset()
{
return offsetof(Y, c);
}
char arr[offset()]; // is 'offset' undefined here?
char c;
};
struct Z
{
static constexpr int f()
{ return g(); } // is 'g' defined here?
static constexpr int g()
{ return 0; }
};
Is the following program well-formed?
constexpr int foo()
{
// is it "outside the definition of
// a constexpr function"?
return bar();
}
char arr[foo()];
constexpr int bar()
{
return 1;
}
int main() {}
If the answer is "yes", the next question:
is the following program well-formed?
constexpr int foo()
{
return bar();
}
char arr[foo()];
constexpr int bar()
{
// cyclic dependency
// (but this is not a recursive function invocation)
return sizeof arr;
}
int main() {}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]