A scalar type is defined as
Trait class that identifies whether T is a scalar type. A scalar type is a type that has built-in functionality for the addition operator without overloads (arithmetic, pointer, member pointer, enum and std::nullptr_t).
It inherits from integral_constant as being either true_type or false_type, depending on whether T is a scalar type, no matter its const and/or volative qualification.
It means pointer is scalar type.
Now if we go to definition of literal type:
A type is a literal type if it is:
- a scalar type; or
- a reference type; or
- an array of literal type; or -a class type (Clause 9) that has all of the following properties:
- it has a trivial destructor,
- every constructor call and full-expression in the brace-or-equal-initializers for non-static data members (if any) is a constant expression (5.19),
- it is an aggregate type (8.5.1) or has at least one constexpr constructor or constructor template that is not a copy or move constructor, and
- all of its non-static data members and base classes are of literal types.
Now, combining above 2 statements, it means pointer is literal type. However pointer can not be constexpr. can someone please clarify?
further see following code:
int a = 7;
constexpr int *pointer1 = &a;
int main ()
{
int b = 4;
constexpr int *pointer2 = &b;
}
pointer1 is fine but pointer 2 gives error. does that mean pointer to global is fine but to automatic variable is not? Does standard mention this anywhere ?
Literal types are the types of constexpr variables and they can be constructed, manipulated, and returned from constexpr functions. Note: the standard doesn't define a named requirement with this name. This is a type category defined by the core language. It is included here as a named requirement only for consistency.
Pointer literal (C++11) The only pointer literal is the nullptr keyword that is a prvalue of type std::nullptr_t . A prvalue of this type is a null pointer constant that can be converted to any pointer type, pointer-to-member type, or bool type. Parent topic: Literals.
A void pointer can hold addresses of any type and can be typecast to any type. It is also called a generic pointer and does not have any standard data type.
In C++, a pointer refers to a variable that holds the address of another variable. Like regular variables, pointers have a data type. For example, a pointer of type integer can hold the address of a variable of type integer. A pointer of character type can hold the address of a variable of character type.
Pointers are literal types. They can be constexpr
under certain conditions:
[expr.const] 6
... [a pointer is
constexpr
if] it contains the address of an object with static storage duration, the address past the end of such an object (5.7), the address of a function, or a null pointer value.
(Where "object with static storage duration" means a global or static object, or a subobject of such object.)
A demo:
int x;
int main()
{
constexpr int *ptr = &x; // Compiles.
// Doesn't compile: `error: '& foo' is not a constant expression`
// int foo;
// constexpr int *bar = &foo;
}
Apparently GCC (with -pedantic-errors -std=c++11
/14
/17
) happily accepts out-of-range constexpr pointer arithmetic: constexpr int *ptr = &x - 10;
, which seems like a bug to me.
Yes they are literals; yes they can be constexpr. To demonstrate:
constexpr int* foo=0;
int x = 7;
constexpr int* ptr=&x;
int main(){}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With