AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 76969417
Accepted
LiDa Cute
LiDa Cute
Asked: 2023-08-24 20:46:59 +0800 CST2023-08-24 20:46:59 +0800 CST 2023-08-24 20:46:59 +0800 CST

Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)?

  • 772

Eu li isso

Promoção integral: pré-valores de tipos integrais pequenos (como char) podem ser convertidos em pré-valores de tipos integrais maiores (como int). - primeira linha
[...detalhes - não importante...]
Observe que todas as outras conversões não são promoções; por exemplo, a resolução de sobrecarga escolhe char -> int (promoção) em vez de char -> short (conversão). - linha final.

A conversão de char -> int é 'promotion' ; está claro (de um byte para 4 bytes)
A ​​conversão de char -> short é 'não promoção'; por que?
Tenho pensado que char tem um byte e short (short int) tem dois bytes. Por que não é considerado uma promoção? Parece contradizer a primeira linha - não significa que 'converter do tipo pequeno para o tipo maior' é promoção? )
-----Editar: depois de procurar algumas respostas:
Podemos considerar "uma promoção é um caso especial de conversão"? , podemos dizer "todas as promoções são conversões, mas nem todas as conversões são promoções"?
Ou deveríamos considerá-los como dois conceitos diferentes e separados?

c++
  • 4 4 respostas
  • 472 Views

4 respostas

  • Voted
  1. Best Answer
    Jan Schultke
    2023-08-24T21:02:53+08:002023-08-24T21:02:53+08:00

    Motivação histórica: C

    A ideia de promoções integrais remonta ao pré-padrão C. Ao fornecer argumentos para funções variadas ( ...) ou para funções sem protótipo, promoções são aplicadas. Ou seja, ligando:

    // function declaration with no prototype
    void mystery();
    // ...
    char c = 'c';
    mystery(c); // this promotes c to int
    
    // in another .c file, someone could define
    void mystery(int x) { /* ... */ }
    

    As promoções são basicamente uma atualização “mínima” do tipo, enquanto as conversões podem ser qualquer coisa. Você poderia até argumentar que o design é uma consequência da construção da linguagem de programação B, que nem sequer tinha vários tipos inteiros como C.

    Redação relevante no padrão C++

    O parágrafo relevante no C++ padrão é:

    Um pré-valor que não é um campo de bits convertido e tem um tipo inteiro diferente de bool, char8_t, , ou cuja classificação de char16_tconversão de inteiro é menor que a classificação de pode ser convertido em um pré-valor do tipo se puder representar todos os valores do tipo de origem ; caso contrário, o pré-valor de origem poderá ser convertido em um pré-valor do tipo .char32_twchar_tintintintunsigned int

    - [conv.prom] p2

    A diferença entre promoções e conversões é explicada aqui:

    As conversões permitidas como promoções integrais estão excluídas do conjunto de conversões integrais.

    - [conv.integral] p4

    Como você pode ver, existe alguma sobreposição entre os dois conceitos, mas qualquer conversão que também seja uma promoção não é considerada uma conversão.

    Impacto na resolução de sobrecarga

    Como você destacou, char -> shorté uma conversão e char -> intuma promoção. Isto tem um impacto significativo na resolução de sobrecarga em alguns casos:

    // A conversion sequence from char -> int is empty
    // because char -> int is a promotion, and so it doesn't contribute
    // to the conversion sequence.
    void f(int);
    // A conversion sequence from char -> short has length 1
    // because char -> short is not a promotion.
    void f(short);
    
    int main() {
        // Not an ambiguous call; calls f(int), because the conversion sequence
        // for this call is shorter.
        // Note that in C, a character literal has type 'int', not 'char', so
        // it is more symmetrical to favor 'int' whenever possible.
        f('x');
    }
    

    Se o C++ fosse projetado do zero hoje em dia, as promoções e conversões provavelmente seriam definidas de maneira muito diferente; no entanto, o status quo é o que temos e é improvável que mude. Mudar esse comportamento e redação depois de todos esses anos é basicamente impossível devido à quantidade de código que depende disso.

    Tal como acontece com tantas decisões de design em C++, a resposta é: razões históricas.

    • 11
  2. Eric Postpischil
    2023-08-24T21:16:04+08:002023-08-24T21:16:04+08:00

    Tanto charpara intquanto charpara shortsão conversões. Observe o uso de “todas as outras conversões” no texto após discutir promoções: Promoções são um tipo de conversão.

    Uma conversão é uma operação que recebe um valor de uma forma e produz o mesmo valor (o mais próximo possível) de outra forma:

    • Pegar um charvalor e produzir um intcom o mesmo valor é uma conversão.
    • Pegar um intvalor e produzir uma string contendo um número decimal representando o mesmo valor é uma conversão.
    • Pegar um peso em libras e produzir o mesmo peso em quilogramas é uma conversão.

    Em muitos lugares das expressões, o C++ converte automaticamente tipos inteiros estreitos em tipos inteiros mais amplos. Isso é feito em grande parte para fins históricos e também porque poderia ser complicado fazer aritmética puramente em tipos restritos - a chararitmética transbordaria muito facilmente e exigir que o programador inserisse explicitamente conversões tornaria o intcódigo complicado.

    Essas conversões especiais são chamadas de “promoções”. O significado natural da palavra em inglês, avançando para uma posição mais elevada, se ajusta a esses tipos de conversões: todas elas convertem de um tipo mais restrito para um tipo mais amplo (ou para um pelo menos tão amplo). Além disso, a palavra é adotada para designar particularmente essas conversões especiais. Uma característica importante das promoções integrais é que elas nunca alteram o valor. (Idealmente, nenhuma conversão alteraria um valor, mas isso acontece devido a restrições. Um exemplo é que a conversão de um floatvalor de 3¼ para intdeve produzir um número inteiro, então 3 é produzido em vez de 3¼. Outro é que a conversão de um intvalor de -3 paraunsignedforça o empacotamento, de modo que um valor nominalmente muito diferente é produzido, embora tenha uma relação especial com o valor de entrada e possa ser considerado o mesmo valor no módulo aritmético.)

    • 8
  3. NoName
    2023-08-24T20:55:34+08:002023-08-24T20:55:34+08:00

    O padrão C++ especifica um conjunto de regras para promoções integrais, e essas regras não são baseadas apenas no tamanho dos tipos. A decisão de promover a charpara an intem vez de a shorté baseada no design histórico da linguagem e no desejo de comportamento consistente em diferentes plataformas.

    De acordo com o padrão C++, as promoções integrais são definidas para converter pequenos tipos integrais em um tipo específico definido pela implementação, que geralmente é int. Como inté escolhido como tipo de destino para promoção integral, a conversão de a charem a shortnão se qualifica como promoção, mesmo que shortseja maior que char. Em vez disso, ele se enquadra na categoria de conversões.

    As regras específicas podem variar entre diferentes implementações e arquiteturas, mas este é o raciocínio geral por trás do comportamento que você observou. Faz parte do design da linguagem, guiado por considerações históricas e aspectos práticos da implementação do compilador, em vez de uma progressão estritamente lógica baseada no tamanho do tipo.

    • 2
  4. Steven Dickinson
    2023-08-24T21:03:04+08:002023-08-24T21:03:04+08:00

    A resposta curta (desculpe o trocadilho) é assim que é definido.

    Claramente, passar de char (1 byte) para short (2 bytes) deve ser uma conversão "segura" (e portanto uma "promoção"?). No entanto, a seção referenciada indica especificamente quais conversões são classificadas como "promoções", e short não existe. É assim que as coisas são. Por que? Não tenho certeza - o texto diz que os operadores aritméticos não aceitam operandos menores que um int e, portanto, talvez não faça sentido "promover" para um short, quando só precisaria ser promovido para int posteriormente.

    • 1

relate perguntas

  • Por que os compiladores perdem a vetorização aqui?

  • Erro de compilação usando CMake com biblioteca [fechada]

  • Erro lançado toda vez que tento executar o premake

  • Como criar um tipo de octeto semelhante a std::byte em C++?

  • Somente operações bit a bit para std::byte em C++ 17?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    destaque o código em HTML usando <font color="#xxx">

    • 2 respostas
  • Marko Smith

    Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}?

    • 1 respostas
  • Marko Smith

    Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)?

    • 2 respostas
  • Marko Smith

    Por que as compreensões de lista criam uma função internamente?

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 respostas
  • Marko Smith

    Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)?

    • 4 respostas
  • Marko Smith

    Por que o construtor de uma variável global não é chamado em uma biblioteca?

    • 1 respostas
  • Marko Smith

    Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto?

    • 1 respostas
  • Marko Smith

    Somente operações bit a bit para std::byte em C++ 17?

    • 1 respostas
  • Martin Hope
    fbrereto Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi Por que as compreensões de lista criam uma função internamente? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A formato fmt %H:%M:%S sem decimais 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python std::views::filter do C++20 não filtrando a visualização corretamente 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa Por que o construtor de uma variável global não é chamado em uma biblioteca? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev Por que os compiladores perdem a vetorização aqui? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan Somente operações bit a bit para std::byte em C++ 17? 2023-08-17 17:13:58 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve