Pergunta

Por que não um compilador ser escrito que administra o que precisa ser código gerenciado em C ++ (ou seja, para torná-lo "CLR compatível")?

Talvez com algum compromisso, como proibindo vazio ponteiros em algumas situações etc. Mas todas essas extra de palavras-chave etc. Qual é o problema que tem de ser resolvido por estas adições?

Eu tenho meus pensamentos sobre alguns aspectos eo que pode ser difícil de resolver, mas uma boa explicação sólida seria muito apreciada!

Foi útil?

Solução

Eu tenho que discordar com as respostas até agora.

O principal problema para entender é que um compilador C ++ cria código que é apropriado para um ambiente muito burra. Até mesmo uma CPU moderna não sabe sobre as funções virtuais, inferno, até mesmo funções são um estiramento. A CPU realmente não se importa que o código de manipulação de exceção para relaxar a pilha está fora de qualquer função, por exemplo. O acordo da CPU em sequências de instruções, com saltos e retornos. Funções certamente não têm nomes, tanto quanto o CPU está em causa.

Por isso, tudo o que é necessário para apoiar o conceito de uma função é colocado lá pelo compilador. Por exemplo. vtables são apenas matrizes do tamanho certo, com os valores corretos do ponto de vista CPUs. __func__ acaba como uma sequência de bytes na tabela de cadeia, o último dos quais é 00.

Agora, não há nada que diz que o ambiente de destino tem que ser burro . Você poderia definitivamente alvo a JVM. Novamente, o compilador tem de preencher o que não é nativamente oferecido. Não há memória cru? Em seguida, alocar uma matriz de bytes grande e usá-lo em seu lugar. Não ponteiros crus? Basta usar inteiro índices nessa matriz de bytes grande.

O principal problema é que o C ++ olhares programa bastante irreconhecível do ambiente de hospedagem. A JVM não é burro, ele sabe sobre as funções, mas espera que eles sejam membros da classe. Ele não espera que eles tenham < e > em seu nome. Você pode contornar isso, mas o que você acabar com é basicamente desconfiguração do nome. E, ao contrário nome desconfiguração hoje, este tipo de desconfiguração do nome não se destina a ligadores C, mas para ambientes inteligentes. Assim, o motor reflexão pode tornar-se convencido de que há uma c__plus__plus classe com função membro __namespace_std__for_each__arguments_int_pointer_int_pointer_function_address, e que ainda é um bom exemplo. Eu não quero saber o que acontece se você tem uma std::map de cordas para reverter iterators.

O outro caminho é realmente muito mais fácil, em geral. Praticamente todas as abstrações de outras línguas pode ser massageado afastado em C ++. Coleta de lixo? Que já é permitido hoje C ++, para que você possa suportar esse mesmo para void*.

Uma coisa que eu não abordou ainda é o desempenho. Emulando memória cru em um array de bytes grande? Isso não vai ser rápido, especialmente se você colocar duplas neles. Você pode jogar um monte de truques para torná-lo mais rápido, mas a que preço? Você provavelmente não está indo para obter um produto comercialmente viável. Na verdade, você pode até com uma linguagem que combina as piores partes do C ++ (lotes de comportamento incomum dependente da implementação), com as piores partes de uma VM (lenta).

Outras dicas

existente código correcto, isto é, código de escrita de acordo com o padrão C ++, não tem de alterar o seu comportamento inadvertidamente.

Bem C ++ / CLI é principalmente concebido para ser uma cola entre código gerenciado e não gerenciado. Como tal, você precisa ter a capacidade de misturar mangaged um conceitos não gerenciados. Você precisa ser capaz de alocar objetos gerenciados e unmanged no mesmo código, então não há nenhuma maneira em torno de palavras-chave separadas.

Por que você não pode compilar C ++ nativo código targetting o CLR?

Sim, você adivinhou certo, haveria muitos compromissos, que tornaria inútil. Eu gostaria de citar apenas três exemplos ...

1) Modelos:. Suportes C ++ eles, o CLR não (genéricos são diferentes). Então você não pode usar a STL, impulsionar etc. no seu código.

.

2) de herança múltipla: apoiado em C ++, não em CLI. Você não poderia mesmo usar a classe iostream padrão e derivados (como stringstream, fstream), que herdam tanto de istream e ostream.

Quase nenhum do código lá fora, seria compilar, você não poderia mesmo implementar a biblioteca padrão.

3) A coleta de lixo.: A maioria dos aplicativos C ++ gerenciar sua memória manualmente (usando ponteiros inteligentes etc.), o CLR tem gerenciamento automático de memória. Assim, o estilo de C ++ "novo" e "delete" seria incompatível com "gcnew", fazendo existente código C ++ inútil para esse novo compilador.

Se você tem que erradicar todas as características importantes, até mesmo a biblioteca padrão, e nenhum código existente seria compilar ... então qual é o ponto?

Em primeiro lugar, a distinção entre "simples C ++" e "administrado C ++" foi intencional, porque um dos propósitos MC ++ era fornecer uma ponte entre o código existente C ++ e CLR.

Em seguida, há apenas muitas características de C ++ que não se encaixam no modelo de CLR. herança múltipla, templates, arithmetics ponteiro ... sem desenhar uma linha clara os programadores seria condenado a erros enigmáticos rosto, tanto em tempo de execução de compilação e.

Eu acho que isso é porque a adição de código gerenciado apresenta em C ++ seria feita C ++ mais lento e o compilador mais complexa. Tanto é assim que C ++ iria perder o que ele é projetado para, em primeiro lugar. Uma das coisas agradáveis ??de C ++ é que é uma linguagem agradável para trabalhar, é o suficiente de baixo nível e ainda um pouco portátil. E provavelmente é isso que os planos do Comitê Padrão ++ do C para o fizeram ficar assim. De qualquer forma eu não acho que C ++ pode nunca ser totalmente "administrado", porque isso significaria que os programas escritos em C ++ precisa de uma VM para executar. Se for esse o caso, por que não usar C ++ / CLI?

Qt quadro faz quase isso. Ou seja, ele tem ponteiros inteligentes, que automaticamente definido como nulo, quando o objeto que eles apontam para seja destruído. E ainda é um C ++ nativo, depois de analisado pelo moc (meta compilador objeto).

Sim, acho que C ++ poderia tornar-se gerenciado. Mas então .NET precisaria ser reescrito para C ++ e não com um viés para BASIC. Com tendo muitas línguas todos sob o mesmo teto. Certas características tem que ir. Foi uma escolha entre VB.NET ou C ++. NET, e VB.NET foi escolhido. Engraçado coisa que ouço é que C # é mais popular do que VB.NET (embora eu uso não!).

O .NET CLR requer que nenhuma referência a um objeto gerenciado pode sempre existir em qualquer lugar o tempo de execução não sabe sobre exceto quando o objeto é fixado; bom desempenho requer que os objetos ser fixado o mínimo possível. Desde o .NET CLR não pode compreender todas as estruturas de dados que são utilizáveis ??dentro C ++, é imperativo que há referências a objetos gerenciados sempre ser mantidas em tais estruturas. Seria possível ter C ++ interagem código "comum" com código .NET, sem quaisquer alterações à linguagem C ++, mas o código única maneira que o C ++ poderia manter qualquer tipo de "referência" para quaisquer objetos .NET seria ter um pouco código no lado do .NET atribuir cada objeto uma alça de algum tipo, e manter uma tabela estática dos objetos associados com os punhos. código C ++ que queria manipular os objetos, então, tem que perguntar o .NET wrapper para executar alguma operação sobre o objeto identificado por uma alça. Adicionando a nova sintaxe torna possível para o compilador para identificar os tipos de objetos do .NET framework precisa saber sobre, e fazer cumprir as restrições necessárias sobre eles.

primeira coisa a considerar é cada coisa que faz c++ "rápido" irá desaparecer. um sistema de coleta de lixo completa em C ++ é quase impossível. porque c++ você pode ter ponteiro quase em qualquer lugar no código. informações de tipo de tempo de execução torna-se caro se não for construído diretamente no sistema langauge que eu. você pode tirar proveito do verdadeiro desempenho nativo. modelo irá desaparecer. verdadeiros ponteiros irá desaparecer. acesso directo à memória se foi.

lista de coisas que teria que ser executada

1. no direct pointers(pointers will get replace with complex refernces)
2. templates (generics pay for preformance)
3. simple c-style arrays (will get wrapped with array structures)
4. programmer no longer has control of whether data is on the stack or
the heap.
5. garbage collection will be enforced(this will cause the most changes to the syntax)
6. runtime type data will get added extensively to the code.
(larger code size)
7.  inlining will become more difficult for the compiler
(no more inline key word)
8. no more inline assembly.
9. the new langauge by now will become incompatible c code.(unless you go through hoops) 

Eu concordo com 5hammer! Se eu deixasse Java e outras linguagens gerenciados que não é à toa: o de ter controle total sobre o computador, memória de acesso gerenciar a memória me, tem controle sobre como o computador irá executar o meu código, integrar-se com bibliotecas C (como Lua). Se eu perder essa flexibilidade, então eu apenas deixar C ++ e cair de volta para C, e se C se torna conseguiu também, então eu iria para a montador.

idiomas gerenciados são os piores de sempre para todas as plataformas de jogos / programas complexos como são delimitadoras você de alguma vacas de sandbox sem acesso direto ao hardware, e são muito mais lento do que linguagens compiladas.

O principal objetivo do C ++ sempre tinha sido performence. É um dos melhores idioma para grandes jogos. E sem este performences língua um monte de jogos não existiria!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top