A seguir estão os benefícios do C ++
- C ++ fornece os recursos específicos sobre os quais eles estão perguntando
- Seu compilador C é quase certamente um compilador C ++, portanto, não há implicações de custo de software
- C ++ é tão portátil quanto C
- O código C ++ pode ser tão eficiente quanto C (ou mais ou menos)
Existem razões concretas e cenários específicos, onde é necessário usar C em vez de C ++?
Referência a esta pergunta: Biblioteca para genéricos em C
Não uma duplicata, porque esta pergunta é sobre as limitações do idioma e não sobre o deve / não deve aprender um idioma em vez de outro.
A postagem de Peter Kirkham foi para mim a mais informativa, principalmente em relação às questões do C99 que eu não havia considerado, então aceitei. Obrigado a todos os outros que participaram.
Respostas:
C é uma linguagem de programação completa. C não é um subconjunto arbitrário de C ++. C não é um subconjunto de C ++.
Este é C válido:
Para fazer a compilação como C ++, você deve escrever:
que não é mais válido C. (você poderia usar o elenco de estilo C, caso em que seria compilado em C, mas seria evitado pela maioria dos padrões de codificação C ++ e também por muitos programadores C; testemunhe os comentários "não elenco malloc" em todo o Stack Overflow) .
Eles não são a mesma linguagem e, se você tiver um projeto existente em C, não deseja reescrevê-lo em uma linguagem diferente apenas para usar uma biblioteca. Você prefere usar bibliotecas com as quais possa interagir na linguagem em que está trabalhando. (Em alguns casos, isso é possível com algumas
extern "C"
funções de invólucro, dependendo de como é o modelo / inline uma biblioteca C ++.)Pegando o primeiro arquivo C em um projeto no qual estou trabalhando, isso é o que acontece se você apenas trocar
gcc std=c99
porg++
:No total, 69 linhas de erros, quatro dos quais são conversões inválidas, mas principalmente para recursos que existem no C99, mas não no C ++.
Não é como se eu estivesse usando esses recursos para me divertir. Seria um trabalho significativo transferi-lo para um idioma diferente.
Portanto, é totalmente errado sugerir que
Freqüentemente, há implicações de custo significativas na portabilidade do código C existente para o subconjunto procedimental do C ++.
Portanto, sugerir 'usar a classe C ++ std :: queue' como uma resposta à pergunta em busca de uma implementação de biblioteca de uma fila em C é mais rápido do que sugerir 'usar C objetivo' e 'chamar a classe Java java.util.Queue usando JNI' ou 'chamar a biblioteca CPython' - Objective C realmente é um superconjunto apropriado de C (incluindo C99), e as bibliotecas Java e CPython podem ser chamadas diretamente de C sem ter que portar código não relacionado para a linguagem C ++.
Claro que você pode fornecer uma fachada C para a biblioteca C ++, mas uma vez que você está fazendo isso, C ++ não é diferente de Java ou Python.
fonte
Sei que não é uma resposta profissional nem específica, mas para mim é simplesmente porque gosto muito de C. C é pequeno e simples e posso caber toda a linguagem em meu cérebro, C ++ para mim sempre pareceu uma grande bagunça com todos os tipos de camadas, tenho dificuldade em grocar. Devido a isso, descubro que sempre que escrevo C ++ acabo gastando muito mais tempo depurando e batendo minha cabeça contra superfícies rígidas do que quando codifico C. Mais uma vez, percebo que muito disso é em grande parte resultado de minha própria 'ignorância'.
Se eu puder escolher, escreverei todas as coisas de alto nível, como a interface e a interação do banco de dados em python (ou possivelmente C #) e todas as coisas que precisam ser rápidas em C. Para mim, isso me dá o melhor de todos os mundos. Escrever tudo em C ++ é como obter o pior de todos os mundos.
Edit: gostaria de acrescentar que acho que C com alguns recursos C ++ é em grande parte uma má ideia se você vai ser várias pessoas trabalhando em um projeto ou se a manutenção é prioridade. Haverá discordância sobre o que constitui 'alguns' e quais bits devem ser feitos em C e quais bits em C ++ levam eventualmente a uma base de código muito esquizofrênica.
fonte
C ++ simplesmente não tem suporte em alguns ambientes do mundo real, como sistemas embarcados de baixo nível. E há uma boa razão para isso: C facilmente bom o suficiente para essas coisas, então por que usar algo maior?
fonte
Eu odeio programar em C ++.
fonte
Alguns motivos podem ser:
Ainda prefiro escrever em C ++ quando posso me safar e, no geral, acho que os benefícios superam as desvantagens. Mas também posso ver o argumento para usar C em alguns casos.
fonte
Existem muitos argumentos sobre programação embarcada, desempenho e outras coisas, eu não os compro. C ++ se compara facilmente a C nessas áreas.Contudo:
Recentemente, depois de programar em C ++ por mais de 15 anos, redescobri minhas raízes em C. Devo dizer que embora existam bons recursos em C ++ que tornam a vida mais fácil, também há uma série de armadilhas e uma espécie de "sempre-existe-uma-maneira-melhor-de-fazer as coisas. Você nunca fica realmente muito feliz com a solução que deu. (Não me entenda mal, isso pode ser uma coisa boa, mas principalmente não).
C ++ oferece tiroteio infinito. O que pode ser indiscutivelmente bom, mas de alguma forma você sempre acaba usando muito disso. Isso significa que você está disfarçando suas soluções com camadas "bonitas" e "bonitas" de abstrações, generalidades, etc.
O que descobri voltando para C foi que era realmente divertido programar novamente. Tendo gasto tanto tempo modelando e pensando sobre como usar melhor a herança, descobri que programar em C na verdade torna meu código-fonte menor e mais legível. É claro que isso depende do seu nível de autodisciplina. Mas é muito fácil colocar muitas abstrações em código direto, o que nunca é realmente necessário.
fonte
infinite gunfire
, ooh sim, é verdade. Nossos pés literalmente tremem :)C tem a principal vantagem de que você pode ver o que realmente está acontecendo quando você olha para algum trecho de código (sim, pré-processador: compile com -E e então você verá). Algo que muitas vezes não é verdade quando você olha para algum código C ++. Lá você tem construtores e destruidores que são chamados implicitamente com base no escopo ou devido a atribuições, você tem sobrecarga de operador que pode ter um comportamento surpreendente, mesmo quando não é mal utilizado. Admito que sou um maníaco por controle, mas cheguei à conclusão de que esse não é um hábito tão ruim para um desenvolvedor de software que deseja escrever um software confiável. Só quero ter uma chance justa de dizer que meu software faz exatamente o que deve fazer e não tem uma sensação ruim no estômago ao mesmo tempo, porque sei que ainda pode haver tantos bugs nele que eu não faria
C ++ também possui modelos. Eu os odeio e amo, mas se alguém disser que os compreende perfeitamente, eu o chamo de mentiroso! Isso inclui os redatores do compilador, bem como as pessoas envolvidas na definição do padrão (o que se torna óbvio quando você tenta lê-lo). Há tantos casos extremos absurdamente enganosos envolvidos que simplesmente não é possível considerá-los todos enquanto você escreve o código real. Eu amo os modelos C ++ por seu poder absoluto. É realmente incrível o que você pode fazer com eles, mas eles também podem levar aos erros mais estranhos e difíceis de encontrar que alguém pode (não) imaginar. E esses erros realmente acontecem e nem mesmo raramente. Ler sobre as regras envolvidas para resolver modelos no ARM C ++ quase fez minha cabeça explodir. E me dá a sensação ruim de perda de tempo tendo que ler mensagens de erro do compilador com vários 1000 caracteres, para as quais eu preciso de 10 minutos ou mais para entender o que o compilador realmente quer de mim. No código C ++ (biblioteca) típico, você também costuma encontrar muitos códigos em arquivos de cabeçalho para possibilitar certos modelos, o que, por sua vez, torna os ciclos de compilação / execução extremamente lentos, mesmo em máquinas rápidas e requer a recompilação de grandes partes do código quando você altera algo há.
C ++ também tem a armadilha const. Você evita const para todos, exceto os casos de uso mais triviais, ou mais cedo ou mais tarde terá que descartá-lo ou refatorar grandes partes da base de código quando ela evoluir, especialmente quando você está prestes a desenvolver um design OO agradável e flexível.
C ++ tem uma digitação mais forte do que C, o que é ótimo, mas às vezes sinto que estou alimentando um Tamagotchi quando tento compilar o código C ++. Uma grande parte dos avisos e erros que normalmente recebo dele não são realmente eu fazendo algo que não funcionaria, mas apenas coisas que o compilador não gosta que eu faça desta forma ou não sem lançar ou colocar algumas palavras-chave extras aqui e há.
Essas são apenas algumas das razões pelas quais não gosto de C ++ para software que escrevo sozinho apenas usando algumas bibliotecas externas supostamente robustas. O verdadeiro horror começa quando você escreve código em equipes com outras pessoas. Quase não importa se eles são hackers de C ++ muito espertos ou iniciantes ingênuos. Todo mundo comete erros, mas C ++ torna deliberadamente difícil encontrá-los e ainda mais difícil identificá-los antes que aconteçam.
Com C ++, você fica simplesmente perdido sem usar um depurador o tempo todo, mas eu gosto de poder verificar a exatidão do meu código na minha cabeça e não ter que depender de um depurador para encontrar meu código rodando em caminhos que eu nunca teria antecipado. Na verdade, tento executar todo o meu código na minha cabeça e tento pegar todos os ramos que ele tem, mesmo em sub-rotinas etc. e usar um depurador apenas ocasionalmente para ver como ele funciona bem em todos os lugares aconchegantes que preparei para isso. Escrever e executar tantos casos de teste que todos os caminhos de código foram usados em todas as combinações com todos os tipos de dados de entrada estranhos é simplesmente impossível. Portanto, você pode não saber dos bugs nos programas C ++, mas isso não significa que eles não existam. Quanto maior se torna um projeto C ++, menor fica minha confiança de que ele não terá muitos bugs não detectados, mesmo se funcionar perfeitamente com todos os dados de teste que temos em mãos. Eventualmente, eu o destruo e começo de novo com alguma outra linguagem ou combinação de outras línguas.
Eu poderia continuar, mas acho que deixei meu ponto claro agora. Tudo isso me fez sentir improdutivo quando programo em C ++ e me fez perder a confiança na exatidão do meu próprio código, o que significa que não o usarei mais, enquanto ainda uso e confio no código C que escrevi mais de 20 anos atrás. Talvez seja simplesmente porque eu não sou um bom programador C ++, ou talvez ser muito bom em C e outras linguagens me permite reconhecer o quão lamer eu realmente sou quando se trata de C ++, e que nunca serei capaz de compreendê-lo totalmente .
A vida é curta...
fonte
Em um ambiente embarcado de baixo nível, alguns dos "engenheiros de software" terão formação em EE e mal dominarão C. C ++ é mais complexo e alguns desses caras simplesmente têm medo de aprender uma nova linguagem. Assim, C é usado como o menor denominador comum. (Antes de sugerir se livrar desses caras, eles são pelo menos tão importantes quanto os especialistas em ciência da computação que não entendem o analógico hardcore.)
Falando por experiência própria em ter herdado e mantido ambos: um design horrível em C é difícil de entender, desenrolar e refatorar em algo utilizável.
Um design horrível em C ++ é infinitamente pior, já que camadas aleatórias de abstração fazem seu cérebro girar rapidamente em torno da base de código tentando descobrir qual código será executado em qual circunstância.
Se tiver que trabalhar com engenheiros que sei que não produzirão grandes projetos, prefiro muito mais o primeiro do que o segundo.
fonte
Não vejo outra razão além da antipatia pessoal, mesmo para a programação de sistemas embarcados e coisas semelhantes. Em C ++, você paga despesas indiretas apenas pelos recursos que usa. Você pode usar o subconjunto C do C ++ em algumas situações específicas em que a sobrecarga do C ++ é muito alta para você. Dito isso, acho que alguns programadores de C superestimam a sobrecarga de algumas construções de C ++. Deixe-me listar alguns exemplos:
Um motivo válido seria quando você está programando para uma plataforma que não tem um compilador C ++ decente (nenhum compilador C ++ ou existe um compilador, mas está implementado de maneira inadequada e impõe uma sobrecarga desnecessária para alguns recursos C ++).
fonte
Por que limitar a fala em inglês? Talvez você seja um autor mais criativo em sérvio.
Esse é o mesmo argumento, com falácias óbvias. Se você tem uma tarefa e suas ferramentas confortáveis resolvem a tarefa com eficiência, você provavelmente usará suas ferramentas confortáveis por um bom motivo.
fonte
C ++ tem uma curva de aprendizado muito mais longa. C tem apenas algumas construções de que você precisa estar ciente e então você pode começar a codificar um software poderoso. Em C ++ você precisa aprender a base C, então o OO e programação genérica, exceção, etc. E depois de um tempo você pode saber a maioria dos recursos e você provavelmente pode usá-los, mas você ainda não sabe como o compilador irá traduzi-los, que overhead implícito eles têm ou não. Isso leva muito tempo e energia.
Para um projeto profissional, esse argumento pode não contar, porque você pode empregar pessoas que já conhecem C ++ muito bem. Mas em projetos de código aberto, onde C ainda é amplamente usado, as pessoas escolhem a linguagem que gostam e são capazes de usar. Considere que nem todo programador de sistema operacional é um programador profissional.
fonte
Eu gostaria de acompanhar a resposta de Dan Olson. Eu acredito que as pessoas temem os recursos potencialmente perigosos e contraproducentes do C ++, e com razão. Mas, ao contrário do que Dan diz, não acho que simplesmente decidir sobre um padrão de codificação seja eficaz, por dois motivos:
Acho que a segunda razão aqui é muito mais importante do que a primeira, porque decidir sobre um padrão de codificação pode facilmente se tornar uma questão política e estar sujeita a revisão posteriormente. Considere o seguinte caso simplificado:
(A alternativa de que o padrão não seja revisado na etapa 3 é empiricamente muito improvável para ser considerada e não seria muito melhor de qualquer maneira.)
Embora eu costumava usar C ++ para quase tudo há alguns anos, estou começando a sentir fortemente que C é preferível em tarefas de baixo nível que precisam ser manipuladas por C ou C ++ e todo o resto deve ser feito em algum outro linguagem inteiramente. (As únicas exceções possíveis são alguns domínios de problemas específicos de alto desempenho, wrt. Blitz ++ )
fonte
Eu uso C, ou pelo menos exporto uma interface C quando escrevo o código da biblioteca.
Eu não quero aborrecimentos mal definidos de ABI.
fonte
Nunca vi nenhum argumento para usar C sobre C ++ que considerasse convincente. Acho que a maioria das pessoas tem medo de certos recursos que o C ++ oferece, muitas vezes com razão. No entanto, isso não me convence, porque é possível impor o uso ou não de determinados recursos por meio de padrões de codificação. Mesmo em C, há muitas coisas que você deseja evitar. Descartar C ++ inteiramente é essencialmente dizer que ele não oferece benefícios tangíveis em relação ao C que ajudariam a escrever um código melhor, que é uma visão que considero bastante ignorante.
Além disso, as pessoas sempre parecem levantar a situação de plataformas onde não existe um compilador C ++. Certamente C seria apropriado aqui, mas acho que você teria dificuldade em encontrar uma plataforma como essa hoje em dia.
fonte
Um ponto que ainda não vi levantado, que considero o mais importante:
A maioria das bibliotecas que uso diariamente são bibliotecas C com vínculos para Python, Ruby, Perl, Java, etc. Pelo que tenho visto, é muito mais fácil agrupar bibliotecas C com 19 vínculos de linguagem diferentes do que agrupar bibliotecas C ++.
Por exemplo, eu aprendi Cairo uma vez e, desde então, usei-o em 3 ou 4 idiomas diferentes. Grande vitória! Prefiro escrever um programa que possa ser usado novamente no futuro, e escrever um que possa ser facilmente adotado para outras linguagens de programação é um caso extremo disso.
Eu sei que é possível ligar bibliotecas C ++, mas AFAICT não é a mesma coisa. Eu usei Qt (v3 e v4) em outras linguagens e não é nem de perto tão bom de usar: eles parecem escrever C ++ em alguma outra linguagem, não como bibliotecas nativas. (Você deve passar sigs do método C ++ como strings!)
C ++ é provavelmente uma linguagem melhor se você estiver escrevendo uma função para ser usada uma vez, ou se você achar que todo o mundo é C ++. C parece ser uma linguagem mais fácil se você estiver projetando para portabilidade de linguagem desde o início.
fonte
O desenvolvimento do kernel do Windows não suporta c ++ (infelizmente).
fonte
Você pode ler um discurso divertido sobre por que Linus Torvalds favorece C aqui
fonte
O código nativo em um mac é objetivo-c. O código nativo em um PC é c (window.h) ou c ++ (mfc). Ambos os ambientes permitirão que você use c com poucas ou nenhuma alteração. Quando quero que uma biblioteca de código seja multiplataforma, ansi c parece uma boa escolha.
fonte
Posso pensar em vários motivos.
Pode não haver um compilador C ++ satisfatório. C ++ é uma linguagem muito maior, e executei compiladores C em sistemas que não seriam capazes de lidar com o C ++ moderno.
O questionador, ou as pessoas com quem ele trabalha, podem estar familiarizados com C, mas não com C ++.
O projeto pode estar em C. Embora seja possível adicionar alguns recursos de C ++ ao C, isso pode facilmente levar a uma bagunça impossível de manter. Eu sugiro escolher um idioma ou outro (geralmente C ++, quando prático).
O questionador pode ter uma visão obsoleta da curva de aprendizado do C ++. (Quando abordado corretamente, é mais fácil do que C. A maioria dos livros introdutórios que vi não aborda isso corretamente.)
Lembre-se de que C e C ++ são duas linguagens diferentes e estão ficando mais diferentes com o tempo. Codificar em ambos ao mesmo tempo é uma má ideia, e usar um subconjunto do C ++ como o C perde a maioria das vantagens do C ++.
fonte
Se você trabalha em um ambiente com duas linguagens, pode usar C para algumas funções críticas de desempenho de baixo nível e uma linguagem mais funcional / de alto nível como C # / Java para a lógica de negócios. Se o código C ++ for usado para essas funções, os C-Wrappers serão necessários para o código JNI / não gerenciado e isso torna as coisas mais complexas do que apenas usar C.
fonte
Eu uso C ++ com programação C por dois motivos:
vector
estring
tirar o gerenciamento de memória do array longe de mimPortanto, é C realmente pegando emprestado alguns C ++, mas usando o compilador C ++ o máximo que posso. Como outra pessoa disse nas respostas, acho que agora estou pegando mais C ++ dessa forma e onde C seria muito envolvente, eu uso C ++. Monitorar / bloquear usando RAII é um desses que usei recentemente ao lidar com programas multi-threaded e outra construção semelhante para abrir / fechar arquivos.
fonte
Acho que C é mais portátil. Eu fiz alguns trabalhos cerca de 5 anos atrás, portando código para muitos sabores de Unix (AIX, Irix, HPUX, Linux). O código C foi fácil de transportar, mas tivemos vários problemas ao transportar parte do código C ++. Talvez fossem apenas ambientes de desenvolvimento imaturos, mas eu preferia usar C em vez de C ++ por este motivo ...
fonte
C é uma linguagem simples, C ++ não. Para muitas pessoas, C ++ é simplesmente muito complicado para dominar totalmente, consulte http://en.wikipedia.org/wiki/C%2B%2B#Criticism .
Por causa da complexidade, diferentes programadores geralmente dominam apenas diferentes subconjuntos da linguagem. Isso torna a leitura do código de outras pessoas dolorosa.
A complexidade e as armadilhas da linguagem adicionam muita distração e, às vezes, prejudicam a produtividade. Em vez de me concentrar no trabalho em si, muitas vezes me peguei lutando com a própria linguagem. Java / python são alternativas mais produtivas.
A depuração de um código C quebrado geralmente é muito mais simples do que depurar um código C ++ quebrado.
Ao contrário do Java / C #, a biblioteca padrão C ++ alcança pouco além do escopo da biblioteca padrão C.
Alguns programadores famosos como Linus Torvalds (Linux) e Richard Stallman (Emacs) não gostam de C ++.
fonte
A maioria dos programadores tem como certo que todos consideram a qualidade uma alta prioridade. Nem sempre é o caso. Se você está acostumado com C, C ++ pode parecer que está fazendo muito por você nos bastidores. A rigidez da verificação de tipo em C ++ também pode parecer restritiva. Muitas pessoas estão dispostas a arriscar introduzir os tipos de bugs que o C ++ pode ajudar a prevenir para evitar esses "incômodos".
fonte
Posso pensar em três razões. Uma é que C é mais adequado para sistemas embarcados, devido ao pequeno tamanho de seus binários e à maior disponibilidade de compiladores C em qualquer sistema. A segunda é a portabilidade: C é uma linguagem menor e o código ANSI C compilará em qualquer lugar. É mais fácil quebrar a portabilidade em C ++. O último é a própria linguagem. C ++ é mais difícil e definitivamente é uma linguagem muito mal projetada. As queixas de Torvalds são relatadas acima. Você também pode consultar as Respostas Frequentemente Questionadas sobre C ++ ( http://yosefk.com/c++fqa/ ).
fonte
A portabilidade pode ser um problema. Diferente da resposta de Gordon Carpenter-Thomp, eu sugeriria que é mais o suporte em tempo de execução de diferentes versões de libstdc ++ em diferentes versões de linux / unix. Veja este link para uma boa discussão sobre isso. Um pequeno trecho:
fonte
Posso seguir muitas sugestões aqui em ambas as direções. Mas no final tudo se resume a a) simples comparável b) complexo comparável.
Não tenho ideia se alguém "inventou" uma espécie de medição da complexidade da linguagem.
Em uma escala de 0 a 10, eu provavelmente classificaria C como 2 ou 3, enquanto C ++ estaria entre 8-10. Eu diria que C ++ é uma das linguagens mais complexas, mas eu não sei, por exemplo, Ada, PL1 ou semelhantes, então talvez não seja tão complexa em comparação com alguma outra linguagem.
C ++ herda toda a complexidade de C, portanto, não pode estar abaixo do nível de complexidade de C.
Eu, de minha parte, ficaria muito mais confortável usando alguma linguagem de script e C. Portanto, no final, é necessário responder à seguinte pergunta. "É mais sempre melhor?"
fonte
A coisa mais útil que encontrei em C é a falta de namespaces e sobrecargas: nomes de função e símbolo são identificadores exclusivos. Para encontrar os locais onde esses símbolos são usados, basta
grep
acessar os arquivos de código-fonte e os resultados da pesquisa mostram os locais.É essencial ao conectar um novo recurso ou componente a um sistema antigo e complicado.
Você não pode fazer isso facilmente em C ++, sem uma ferramenta sofisticada de construção de gráficos de chamadas.
fonte
A maioria das pessoas parece pensar que C e C ++ estão de alguma forma relacionados, mas estão redondamente enganados. C ++ é uma linguagem completamente diferente de C.
Em C ++, você pensa em termos de objetos e como eles se relacionam uns com os outros. Em C, você pensa em termos de APIs. É como a diferença entre o dia e 17.
Uma analogia pobre: se alguém adicionar chinês ao inglês e chamá-lo de inglês ++, você provavelmente não se sentiria confortável em adicionar uma frase em chinês à sua última carta de amor, porque é muito mais fácil expressar amor nesta parte do inglês ++.
fonte
A seguir estão todas as razões pelas quais pode ser benéfico limitar um projeto a C:
fonte