O que é o uso de nomes de caracteres universais em identificadores em C ++

11

O padrão C ++ (notei no novo, mas já existia no C ++ 03) especifica nomes de caracteres universais, escritos como \uNNNNe \UNNNNNNNNe representando os caracteres com pontos de código unicode NNNN/ NNNNNNNN. Isso é útil com literais de cadeia, especialmente porque também são definidos literais de cadeia explicitamente UTF-8, UTF-16 e UCS-4. No entanto, os literais de caracteres universais também são permitidos nos identificadores. Qual é a motivação por trás disso?

A sintaxe é obviamente totalmente ilegível, os identificadores podem ser alterados para o vinculador e não é como se houvesse alguma função padrão para recuperar símbolos pelo nome de qualquer maneira. Então, por que alguém realmente usaria um identificador com literais de caracteres universais?

Edit: Como ele já existia no C ++ 03, uma pergunta adicional seria se você realmente viu um código que o usou?

Jan Hudec
fonte

Respostas:

6

ATUALIZAÇÃO - essa resposta, embora pareça fazer sentido para mim e para os outros, acaba por estar amplamente errada (e suficientemente errada em relação à intenção, como efetivamente errada). Como (como apontado em um comentário do AProgrammer), não é permitido usar o UCS fora das constantes da string quando o mesmo caractere pode ser representado normalmente no conjunto de caracteres base. Portanto, não é possível usá-lo para escapar de palavras-chave, como no meu exemplo; e não usá-lo para criar 'identificadores' 23skiddoescapando do2. Ainda poderia ser usado para tornar os nomes compatíveis com idiomas externos, eu acho, mas apenas ao que parece, quando esses nomes começam com uma letra ou um caractere estendido e contêm apenas letras, dígitos, sublinhado e caracteres estendidos - o que parece muito restritivo para apoiar adequadamente essa intenção. Portanto, deve ser que a intenção principal seja (como na resposta do AProgrammer) permitir esses caracteres extras nos identificadores e habilitar os editores de origem onde esses caracteres são exibidos graficamente, enquanto ainda permite que o arquivo de origem esteja em ASCII simples.


Programas C ++ podem chamar funções escritas em outros idiomas. É uma boa estratégia por parte do comitê de padronização garantir que o C ++ seja interoperável com outros idiomas, o que pode permitir caracteres não alfanuméricos ou unicode nos nomes das funções, mesmo que esses idiomas ainda não existam. O padrão não precisa especificar como isso funcionará no nível do vinculador, etc; mas é bom ter um mecanismo especificado em vigor para permitir isso.

Você não precisa olhar para o futuro para ver uma utilidade para isso. Suponha que eu tenha uma biblioteca C antiga com uma função chamada catch(ou protegida ou mutável) ... e que eu queira chamá-la de C ++. E por qualquer motivo, não posso ou não quero modificar o código C (a propósito, mais de uma vez tive que lidar com códigos C antigos que usavam um nome de função que se tornara uma palavra-chave C ++ ...)

Com nomes de UC, posso escrever isso em um cabeçalho e, em seguida, basta chamar 'catch_func ()':

extern "C" {
       int catc\u0068( int a, int b );  // C 'catch()' function
}
inline int catch_func( int a, int b ) { return catc\u0068(a,b); }

Claro que é feio, mas não importa, pois está apenas em um lugar no cabeçalho. A mesma abordagem pode ser usada para criar stubs para chamar funções em outros idiomas e funciona mesmo se os nomes forem palavras-chave em C ++ ou unicode, ou tiverem espaços .ou outra pontuação incorporada neles

Vários outros idiomas possuem dispositivos que permitem a criação de identificadores que não seguem o padrão geral; por exemplo em Verilog, \abcdé um identificador equivalente a abcd, mas \whilee \23skidooe \44.e2são identificadores também, que necessitam o prefixo barra invertida para ser vistos como tal. Devido à maneira como o Verilog é usado, é importante permitir qualquer nome, onde eles se relacionam com interfaces externas.

Greggo
fonte
Caso de uso interessante. Embora eu suspeite (quando possível), seria melhor escrever um pequeno arquivo C para traduzir o nome (e, portanto, pode usar o identificador C ++) e fazer com que o C ++ chame essa função C.
Thomas Eding
1
Você não pode escrever isso por dois motivos: o primeiro UCS fora da cadeia de caracteres e os caracteres literais não podem se referir ao caractere nos conjuntos básicos sem tornar o programa malformado; segundo, se essa cláusula não estava presente, o UCS é tratado na fase 1 da tradução e portanto, não haveria diferença na manipulação entre um UCS referente a um caractere no conjunto básico e o próprio caractere.
AProgrammer
4

Ele permite que um sistema permita que caracteres unicode no identificador exportem a fonte em um formato compilável em qualquer compilador em conformidade padrão. IE, é uma maneira de codificar unicode sobre o conjunto de caracteres básico (mais ou menos como o print-quote é usado para email, sistemas que sabem melhor são capazes de fazer um trabalho melhor, outros sistemas ainda estão funcionando).

AProgrammer
fonte
2

Alguém pode querer criar um identificador usando um caractere de idioma estrangeiro que não possa ser digitado no teclado ou no dispositivo de entrada. Como alternativa, o identificador pode conter um caractere que não é imprimível usando os recursos de fonte ou saída do dispositivo, mas o IDE deseja mostrar uma representação precisa.

Akton
fonte
4
No primeiro caso, o identificador não pareceria ter esse caractere; portanto, o código seria ilegível e o identificador realmente não importa para a máquina. E, para o segundo, a representação no IDE é um problema completamente separado.
Jan Hudec
1

O C ++ exige que os caracteres estendidos reais que aparecem literalmente na fonte se comportem de forma idêntica aos Nomes Universal de Caracteres. Permitir nomes de caracteres universais nos identificadores permite que os programadores usem caracteres estendidos nos identificadores.

bames53
fonte
Se caracteres estendidos reais são suportados, eles devem se comportar como caracteres universais correspondentes. Mas eles não precisam ser apoiados.
Jan Hudec
1
Isso é verdade, mas meio que perde o objetivo, ou seja, se o comitê deseja especificar que as implementações que suportam caracteres estendidos devem suportar o uso desses caracteres nos identificadores, isso exige que as UCNs sejam permitidas nos identificadores. Ou seja, UCNs são permitidos em identificadores, não necessariamente porque são tão legíveis e todo mundo adora codificar nomes manualmente em hexadecimal, mas porque se a especificação deseja permitir que caracteres estendidos sejam usados ​​em identificadores, é necessário especificar que UCNs são permitidos em identificadores.
bames53