Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

206
Visualizações
Two adjacent ## operators

Can someone explain me why having 2 concatenation operators does not produce any error by a preprocessor?:

#define Z(x) x ## ## 3
Z(3)

results in:

33

Standards say that:

...each instance of a ## preprocessing token in the replacement list (not from an argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing token

so I would expect that preprocesor first tries to concat x with second ## which seems strange. This does not produce any valid token so I would expect at least a warning. Neither gcc, nor VC produce any warning.

I would appreciate some explanation of how this works and why. Standard mentions placemaker temporary tokens which would explain why this works but there would have to be one such token between both 'double-sharps'. The problem is that placemaker tokens are generated when parameter contains no tokens and there is no parameter between both concat operators.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

(The C and C++ standards have essentially identical wording in §6.10.3.3 and §16.3.3 respectively. In case there are minor differences, I took the quotes from C11.)

The order in which ## operators are processed is explicitly unspecified: ("The order of evaluation of ## operators is unspecified.", last sentence of paragraph 3; also see paragraph 2 of the preceding section). So you can't say that the "preprocesor first tries to concat x with second ##"; it might first try to concat the first ## with the 3. That wouldn't produce a valid token, either, so it's a bit of a quibble. But it's important to remember.

The question is whether the statement that the order of evaluation being unspecified permits the evaluation to be interleaved. In other words, could a preprocessor satisfy the standard by first deleting the second ##, then deleting the first one, and finally producing a single concatenation? Certainly, in the execution model, it is clear that unsequenced operations are allowed to interleave. (See note 13 in §5.1.2.3. In C++, the words are "can overlap"; §1.9/13)

That might be a bit of a stretch, but it's also worth noting that after concatenation:

If the result is not a valid preprocessing token, the behavior is undefined.

This is not marked as a constraint, so an error message is not required. And since undefined behaviour relieves the compiler from any obligation to the standard, I suppose gcc is totally within its rights to produce the observed behaviour.

In short, the macro replacement string provided in the original question either involves unspecified or undefined behaviour, but not a constraint violation. Consequently, the compiler is under no obligation to produce a diagnostic.

Not producing a diagnostic in this case could be considered a quality-of-implementation issue. On the other hand, I don't know of any compiler which produces a warning for macros with ambiguous ## order of evaluation. Aside from the constraint that a macro expansion list cannot start or end with a ## token, which must be diagnosed by the compiler, it is wholly the responsibility of the programmer to ensure that concatenation expressions are well-defined.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda