Los objetos, las referencias, las funciones (incluidas las especializaciones de plantillas de funciones) y las expresiones tienen propiedades llamadas tipos , que restringen las operaciones permitidas en estas entidades y proporcionan significado semántico a secuencias de bits que de otro modo serían ordinarias.
Macros y tipos básicos adicionales
Constante de puntero nulo definida por la implementación
NULL
definido en el archivo de encabezado |
||
definido en el archivo de encabezado |
||
definido en el archivo de encabezado |
||
definido en el archivo de encabezado |
||
definido en el archivo de encabezado |
||
definido en el archivo de encabezado |
||
definido en el archivo de encabezado |
||
#define NULL /*definido por implementación*/ |
La macro NULL
es una constante de puntero nulo definida por la implementación que se puede
expresión constante literal rvalue de tipo entero que se evalúa como cero |
(anterior a C++11) |
un literal entero con valor cero o un valor pr de tipo std::nullptr_t |
(desde C++11) |
Una constante de puntero nulo es implícitamente convertible a cualquier tipo de puntero; el resultado de esta conversión es un valor de puntero nulo de ese tipo. Si una constante de puntero nulo tiene un tipo entero, también se puede convertir en un valor pr de tipo std::nullptr_t.
posible implementación
#define NULL 0
// C++11 起
#define NULL nullptr
Aviso
En C, las macros NULL
pueden tener tipos void*
, pero esto no está permitido en C++.
Ejemplo de llamada
#include <cstddef>
#include <type_traits>
#include <iostream>
class S;
int main()
{
int* p = NULL;
int* p2 = static_cast<std::nullptr_t>(NULL);
void(*f)(int) = NULL;
int S::*mp = NULL;
void(S::*mfp)(int) = NULL;
if (std::is_same<decltype(NULL), std::nullptr_t>::value)
{
std::cout << "NULL implemented with type std::nullptr_t" << std::endl;
}
else
{
std::cout << "NULL implemented using an integral type" << std::endl;
}
return 0;
}
producción
Un tipo trivial con requisitos de alineación de memoria no menores que los de cualquier tipo subyacente.
std::max_align_t
definido en el archivo de encabezado |
||
typedef /*definido por implementación*/ max_align_t; |
(desde C++11) |
Aviso
Los punteros devueltos por funciones de asignación como std::malloc son adecuados para alinear cualquier objeto, lo que significa que la alineación es al menos tan estricta como std::max_align_t .
std::max_align_t suele ser sinónimo del tipo escalar más grande, doble largo en la mayoría de las plataformas, y su requisito de alineación es 8 o 16.
Ejemplo de llamada
#include <iostream>
#include <cstddef>
int main()
{
std::cout << "alignof(std::max_align_t): "
<< alignof(std::max_align_t) << std::endl;
return 0;
}
producción
El desplazamiento de bytes desde el inicio del tipo de diseño estándar hasta su miembro especificado
offsetof
definido en el archivo de encabezado |
||
#define offsetof(tipo, miembro) /*definido por implementación*/ |
La macro offsetof se expande a una expresión constante entera de tipo std::size_t. Su valor es el número de bytes desplazados desde el principio del objeto de tipo especificado hasta su miembro especificado, incluidos los bytes de relleno si los hay.
Si no es un tipo de diseño estándar, el comportamiento no está definido (antes de C++ 17) . El uso de macros se type
admite condicionalmente (desde C++ 17).offsetof
Si member
es un miembro estático o una función miembro, el comportamiento no está definido.
El desplazamiento del primer miembro de un tipo de diseño estándar es siempre cero (la optimización de la clase base vacía es obligatoria).
Una expresión offsetof(type, member)
nunca depende de un tipo y depende de un valor si y sólo si el tipo es dependiente.
anormal
offsetof
No se lanza ninguna excepción; la expresión noexcept(offsetof(type, member)) siempre se evalúa como verdadera.
Aviso
offsetof
No se puede implementar en C++ estándar y requiere compatibilidad con el compilador: GCC , LLVM
Ejemplo de llamada
#include <iostream>
#include <cstddef>
struct S
{
char c;
double d;
};
int main()
{
std::cout << "the first element is at offset "
<< offsetof(S, c) << std::endl
<< "the double is at offset "
<< offsetof(S, d) << std::endl;
return 0;
}