prioridad fundido estilo C ++

I. ¿Por qué es consciente de este problema

Antes de utilizar el tiempo de lanzamiento al estilo de C, un lugar más molesto es debida operación de conmutación de prioridad, lo que resulta en el tipo de conversión de la necesidad de utilizar soportes adicionales se mantienen, aspecto muy hinchado. Más tarde, me di aparentemente mayor prioridad en operadores de conversión de estilo C ++, aunque la potencia se ha incrementado, pero cuando la entrada es relativamente suave, y por lo tanto parece más procesos.
@ Harry tsecer: CAT cpp.style.cast.cpp -n
. 1 struct S
2 {
. 3 int X;
. 4};
. 5
. 6 int foo (void * VP)
. 7 {
. 8 retorno static_cast <const * S> (VP) -> X
. 9 + (S *) (VP) -> X;
10}
tsecer Harry @: G ++ -C cpp.style.cast.cpp
cpp.style.cast.cpp: la función de 'foo int (void *)' en la que:
cpp.style.cast.cpp: 9: 14: error: 'void *' no es un tipo de objeto que apunta
+ (S *) (VP) -> X;
^
tsecer @ Harry:

Dos, la prioridad fundido

En el lenguaje C, define claramente la prioridad de los actores ,

prioridad operadores descripción asociatividad
1 :: resolución de alcance De izquierda a derecha
2 a++   a-- Sufijo de incremento y decremento
type()   type{} transformación de estilo funcional
a() llamada a la función
a[] subíndice
.   -> Acceso miembros
3 ++a   --a Prefijo de incremento y decremento De derecha a izquierda
+a   -a Un yuan suma y resta
!   ~ La lógica no y bit a bit NO
(type) transformación de estilo C
*a Indirecta (dereference)
&a sitio de toma
sizeof tamaño de la toma [Nota 1]
co_await expresión await  (C ++ 20)
new   new[] Asignación dinámica de memoria
delete   delete[] Asignación dinámica de memoria

 

Su prioridad y "incremento prefijo" (+) mismo, por debajo de la "Acceso Miembro" (->) prioridad. Pero para C ++ fundido estilo, que las "notas" es la
tabla no incluye const_cast, static_cast, dynamic_cast, reinterpret_cast, typeid, sizeof ..., noexcept y alignof, porque nunca tienen ambigua.
Pero no especificó su prioridad. Un mensaje el desbordamiento de la pila de los temas tratados .

Tres, gcc procesada en la sintaxis

Se puede ver en la implementación de la función para C ++ fundido estilo, siempre y cuando identificar const_cast, static_cast, dynamic_cast, reinterpret_cast, palabra clave, detrás del procedimiento es Yimapingchuan, luego debe ser seguido por un ángulo izquierdo soporte / signo menor que (RT_LESS), tipo (typeid), el soporte de ángulo recto / mayor que el número (RT_GREATER), un paréntesis izquierdo (RT_OPEN_PAREN), la expresión (expresión), hay soportes (RT_CLOSE_PAREN). La clave es, después de la finalización de estas llamadas analíticas, directos build_dynamic_cast / build_static_cast / build_reinterpret_cast / build_const_cast para generar una expresión, en este sentido, C ++ fundido estilo es más como una operación atómica, la totalidad de su estructura gramatical constituye un elemento fundamental unidad .
4.9.0-CCG \ GCC \ CP \ parser.c
/ * Analizar la expresión-A El Postfix.

postfix-expresión:
primaria-expresión
postfix-expresión [expresión]
postfix-expresión (expresión-list [opt])
simple de tipo especificador (expresión-list [opt])
nombretipo :: [opt] identificador de nombre especificador anidado
( lista de expresión [opt])
nombretipo :: [opt] nombre-plantilla-especificador anidado [opt] plantilla-id
(lista de expresión [opt])
postfix-expresión. plantilla [opt] id-expresión
de sufijo-expresión -> plantilla [opt] id-expresión
de sufijo-expresión. pseudo-destructor-nombre
postfix-expresión -> pseudo-destructor-nombre
postfix-expresión ++
postfix-expresión -
dynamic_cast <tipo-id> (expresión)
static_cast <typeid> (expresión)
reinterpret_cast <typeid> (expresión)
const_cast <typeid> (expresión)
typeid (expresión)
typeid (typeid)

Extensión de GNU:

postfix-expresión:
(tipo-id) {inicializador de vinos, [opt]}

Esta extensión es una versión GNU del compuesto-literal C99
constructo. (El C99 usos gramaticales `nombre-tipo 'en lugar de` Tipo-id',
pero son esencialmente el mismo concepto.)

Si ADDRESS_P es cierto, la expresión de sufijo es el operando de la
&' operador'. CAST_P es cierto si esta expresión es el objetivo de un
molde.

Si MEMBER_ACCESS_ONLY_P, que sólo permiten expresiones de sufijo que son
la clase de acceso miembro de expresiones [expr.ref].

Devuelve una representación de la expresión. * /

árbol estática
cp_parser_postfix_expression (cp_parser * analizador, address_p bool, cast_p bool,
member_access_only_p bool, decltype_p bool,
cp_id_kind * pidk_return)
{
cp_token * ficha;
loc location_t;
enum palabra clave librado;
cp_id_kind idk = CP_ID_KIND_NONE;
postfix_expression árbol = NULL_TREE;
bool is_member_access = false;
int saved_in_statement = -1;

/ * Peek en el siguiente token. * /
Token = cp_lexer_peek_token (parser-> lexer);
loc = tokens> ubicación;
/ * Algunas de las producciones están determinados por palabras clave. * /
Palabra clave = tokens> palabra clave;
Interruptor (palabra clave)
{
caso RID_DYNCAST:
caso RID_STATCAST:
caso RID_REINTCAST:
caso RID_CONSTCAST:
{
tipo de árbol;
la expresión del árbol;
const char * saved_message;
bool saved_in_type_id_in_expr_p;

/ * Todo esto se puede realizar de la misma manera desde el punto
de vista del análisis sintáctico. Comience por consumir el token
identificar la colada. * /
Cp_lexer_consume_token (parser-> lexer);

/ * Nuevos tipos no pueden ser definidas en el reparto. * /
Saved_message = parser-> type_definition_forbidden_message;
parser-> type_definition_forbidden_message
= G _ ( "tipos no pueden definirse en moldes");

/ * Busca la apertura `<'. * /
Cp_parser_require (parser, CPP_LESS, RT_LESS);
/ * Analizar el tipo al que estamos fundición. * /
Saved_in_type_id_in_expr_p = parser-> in_type_id_in_expr_p;
parser-> in_type_id_in_expr_p = true;
type = cp_parser_type_id (parser);
parser-> in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
/ * Busca el cierre `>'. * /
Cp_parser_require (parser, CPP_GREATER, RT_GREATER);
/ * Restaurar el mensaje de edad. * /
Parser-> type_definition_forbidden_message = saved_message;

bool saved_greater_than_is_operator_p
= parser-> greater_than_is_operator_p;
parser-> greater_than_is_operator_p = true;

/ * Y la expresión que está siendo lanzado. * /
Cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
expresión = cp_parser_expression (parser, / * cast_p = * / true, y idk);
cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);

parser-> greater_than_is_operator_p
= saved_greater_than_is_operator_p;

/ * Único tipo conversiones a tipos integrales o de enumeración
se pueden usar en constantes-expresiones. * /
Si (cast_valid_in_integral_constant_expression_p (tipo)!
&& cp_parser_non_integral_constant_expression (analizador, NIC_CAST))
error_mark_node retorno;

interruptor (palabra clave)
{
caso RID_DYNCAST:
postfix_expression
= build_dynamic_cast (tipo, expresión, tf_warning_or_error);
descanso;
caso RID_STATCAST:
postfix_expression
= build_static_cast (tipo, expresión, tf_warning_or_error);
descanso;
caso RID_REINTCAST:
postfix_expression
= build_reinterpret_cast (tipo, expresión,
tf_warning_or_error);
descanso;
caso RID_CONSTCAST:
postfix_expression
= build_const_cast (tipo, expresión, tf_warning_or_error);
descanso;
por defecto:
gcc_unreachable ();
}
}
Romper;
......
}

Supongo que te gusta

Origin www.cnblogs.com/tsecer/p/12532736.html
Recomendado
Clasificación