Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

178
Vistas
Efecto de hash único en macro similar a un objeto

¿Se permite # en una macro similar a un objeto y, de ser así, qué sucede?

El estándar C solo define el comportamiento de # en una macro para macros similares a funciones.

Código de muestra:

 #include <stdio.h> #define AX#Y #define B(X) #X #define C(X) B(X) int main() { printf(C(A) "\n"); }

gcc genera X#Y , lo que sugiere que permite que # esté presente y no realiza ningún procesamiento especial. Sin embargo, dado que la definición del operador # no define el comportamiento en este caso, ¿es realmente un comportamiento indefinido?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Como notó, # solo tiene un efecto definido en macros similares a funciones. § 6.10.3.2/1 (todas las referencias al estándar son al borrador C11 ( N1570 )). Para ver lo que sucede en las macros de tipo objeto, debemos buscar en otra parte.

Una directiva de preprocesamiento de la forma

 # define identifier replacement-list new-line

define una macro similar a un objeto que hace que cada instancia subsiguiente del nombre de la macro sea reemplazada por la lista de reemplazo de tokens de preprocesamiento que constituyen el resto de la directiva. [...]

§ 6.10.3/9

Por lo tanto, la única pregunta es si # está permitido en una replacement-list . Si es así, participa en el reemplazo como de costumbre.

Encontramos la sintaxis en § 6.10/1 :

 replacement-list: pp-tokens (opt.) pp-tokens: preprocessing-token pp-tokens preprocessing-token

Ahora, ¿es # un preprocessing-token válido? § 6.4/1 dice:

 preprocessing-token: header-name identifier pp-number character-constant string-literal punctuator each non-white-space character that cannot be one of the above

Ciertamente no es un header-name ( § 6.4.7/1 ), no está permitido en identifier ( § 6.4.2.1/1 ), ni es un pp-number (que es básicamente cualquier número en un formato permitido, § 6.4.8/1 ), ni una character-constant (como u'c' , § 6.4.4.4/1 ) o un string-literal (exactamente lo que esperaría, por ejemplo, L"String" , § 6.4.5 /1 ).

Sin embargo, aparece como un punctuator en § 6.4.6/1 . Por lo tanto, está permitido en la replacement-list de una macro similar a un objeto y se copiará palabra por palabra. Ahora está sujeto a volver a escanear como se describe en § 6.10.3.4 . Veamos tu ejemplo:

C(A) será reemplazado por C(X#Y) . # no tiene ningún efecto especial aquí, porque no está en la replacement-list de C , sino en su argumento. C(X#Y) obviamente se convierte en B(X#Y) . Luego, el argumento de B se convierte en una cadena literal a través del operador # en la replacement-list B , lo que produce "X#Y"

Por lo tanto, no tienes un comportamiento indefinido.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda