Como desenvolvedor de Linux (servidor), não sei onde e por que devo usar o C ++.
Quando vou para a performance, a primeira e a última escolha é C.
Quando "performance" não é o principal problema, linguagens de programação como Perl e Python seriam boas escolhas.
Quase todos os aplicativos de código aberto que conheço nesta área foram escritos em C, Perl, Python, script Bash, AWK ou até PHP, mas ninguém usa C ++.
Não estou discutindo outras áreas, como GUI ou aplicativos da Web, apenas falando sobre Linux, CLI e daemons.
Existe algum motivo satisfatório para usar C ++?
Respostas:
E é aí que você deve fazer backup. Agora, não posso, de maneira alguma , falar em desenvolvimento de servidores. Talvez não haja realmente um motivo convincente para preferir o C ++ em vez das alternativas.
Mas, de um modo geral, a razão para usar C ++ em vez de outras linguagens é realmente o desempenho. A razão para isso é que o C ++ oferece um meio de abstração que, diferentemente de todas as outras linguagens que eu conheço, não apresenta sobrecarga de desempenho no tempo de execução.
Isso permite escrever código muito eficiente que ainda possui um nível de abstração muito alto.
Considere as abstrações usuais: funções virtuais, ponteiros de função e o idioma PIMPL. Tudo isso depende de uma indireção em tempo de execução resolvida pela aritmética do ponteiro. Em outras palavras, incorre em um custo de desempenho (por menor que seja).
C ++, por outro lado, oferece um mecanismo de indireção que não incorre em nenhum custo (desempenho): modelos. (Essa vantagem é paga com um (às vezes muito) tempo de compilação aumentado.)
Considere o exemplo de uma função de classificação genérica.
Em C, a função
qsort
usa um ponteiro de função que implementa a lógica pela qual os elementos são ordenados em relação um ao outro. AArrays.sort
função do Java vem em várias variantes; um deles classifica objetos arbitrários e exige que umComparator
objeto seja passado para ele, que funciona como o ponteiro de função em C'sqsort
. Mas há várias outras sobrecargas para os tipos Java "nativos". E cada um deles possui uma cópia dosort
método - uma duplicação horrível de código.Java ilustra uma dicotomia geral aqui: ou você tem duplicação de código ou incorre em uma sobrecarga de tempo de execução.
Em C ++, a
sort
função funciona da mesma forma queqsort
em C, com uma pequena mas fundamental diferença: o comparador que é passado para a função é um parâmetro de modelo . Isso significa que sua chamada pode ser incorporada . Não é necessário indireção para comparar dois objetos. Em um circuito fechado (como é o caso aqui), isso pode realmente fazer uma diferença substancial.Não é de surpreender que a
sort
função C ++ supere os Cssort
mesmo que o algoritmo subjacente seja o mesmo. Isso é especialmente perceptível quando a lógica de comparação real é barata.Agora, eu estou não dizendo que C ++ é a priori mais eficiente do que C (ou outras línguas), nem que a priori oferece uma abstração mais elevado. O que ele oferece é uma abstração muito alta e incrivelmente barata ao mesmo tempo, para que você geralmente não precise escolher entre código eficiente e reutilizável.
fonte
Arrays.sort
implementações de Java ). Somente você perde a vantagem da alta abstração. Esta não é uma desvantagem específica dos modelos, é uma desvantagem da duplicação de código em geral. Além disso, isso tende a não ter importância, pois em ciclos apertados, geralmente é sempre o mesmo código carregado.vector.push_back
paravector<int>
e outro paravector<float>
, mas, ao trabalhar com umvector<int>
, há poucas razões pelas quais ovector<float>
código estaria no cache de instruções. Portanto, não vejo como isso realmente importa. a instanciação individual do modelo é altamente otimizada e geralmente mais compacta do que as implementações genéricas genéricasEu vejo muitos programadores em C que odeiam C ++. Levei algum tempo (anos) para entender lentamente o que é bom e o que é ruim. Eu acho que a melhor maneira de expressar isso é esta:
Menos código, sem sobrecarga de tempo de execução, mais segurança.
Quanto menos código escrevermos, melhor. Isso rapidamente fica claro em todos os engenheiros que buscam a excelência. Você corrige um bug em um lugar, não muitos - você expressa um algoritmo uma vez e o reutiliza em muitos lugares, etc. Os gregos têm até um ditado, que remonta aos antigos espartanos: "dizer algo em menos palavras, significa que você é sábio sobre isso ". E o fato é que, quando usado corretamente , o C ++ permite que você se expresse em muito menos código que C, sem custar a velocidade do tempo de execução, sendo mais seguro (ou seja, capturando mais erros em tempo de compilação) do que C é.
Aqui está um exemplo simplificado do meu renderizador : Ao interpolar valores de pixel na linha de varredura de um triângulo. Eu tenho que começar a partir de uma coordenada X x1 e alcançar uma coordenada X x2 (da esquerda para a direita de um triângulo). E em cada etapa, em cada pixel que passo, tenho que interpolar valores.
Quando interpolo a luz ambiente que atinge o pixel:
Quando interpolo a cor (chamada sombreamento "Gouraud", onde os campos "vermelho", "verde" e "azul" são interpolados por um valor de etapa em cada pixel):
Quando renderizo no sombreamento "Phong", não interpolo mais uma intensidade (ambientLight) ou uma cor (vermelho / verde / azul) - interpolo um vetor normal (nx, ny, nz) e, a cada passo, tenho que voltar -calcular a equação da iluminação, com base no vetor normal interpolado:
Agora, o primeiro instinto dos programadores em C seria "heck, escreva três funções que interpolam os valores e os chame dependendo do modo definido". Primeiro de tudo, isso significa que tenho um problema de tipo - com o que trabalho? Meus pixels são PixelDataAmbient? PixelDataGouraud? PixelDataPhong? Oh, espere, diz o eficiente programador C, use uma união!
..e então, você tem uma função ...
Você sente o caos entrando?
Antes de tudo, basta digitar um erro de digitação para travar meu código, pois o compilador nunca vai me parar na seção "Gouraud" da função para acessar realmente o ".a". valores (ambientais). Um erro não detectado pelo sistema do tipo C (ou seja, durante a compilação), significa um erro que se manifesta no tempo de execução e requer depuração. Você notou que estou acessando
left.a.green
no cálculo de "dgreen"? O compilador certamente não lhe disse isso.Então, há repetição em todos os lugares - o
for
loop existe quantas vezes houver modos de renderização, continuamos fazendo "direita menos esquerda dividida por etapas". Feio e propenso a erros. Você notou que eu comparo usando "i" no loop Gouraud, quando eu deveria ter usado "j"? O compilador está novamente silencioso.E o if / else / ladder para os modos? E se eu adicionar um novo modo de renderização em três semanas? Lembrarei de lidar com o novo modo em todo o "if mode ==" em todo o meu código?
Agora compare a feiúra acima, com este conjunto de estruturas C ++ e uma função de modelo:
Agora veja isso. Não fazemos mais um tipo de sopa de união: temos tipos específicos para cada modo. Eles reutilizam suas coisas comuns (o campo "x") herdando de uma classe base (
CommonPixelData
). E o modelo torna o compilador CREATE (isto é, gera código) as três funções diferentes que teríamos escrito em C, mas, ao mesmo tempo, sendo muito rigoroso quanto aos tipos!Nosso loop no modelo não pode brincar e acessar campos inválidos - o compilador latirá se o fizermos.
O modelo executa o trabalho comum (o loop, aumentando em "etapa" a cada vez)) e pode fazer isso de uma maneira que simplesmente NÃO PODE causar erros de tempo de execução. A interpolação por tipo (
AmbientPixelData
,GouraudPixelData
,PhongPixelData
) é feito com ooperator+=()
que vamos adicionar os estruturas - que basicamente ditam como cada tipo é interpolada.E você vê o que fizemos com o WorkOnPixel <T>? Queremos fazer um trabalho diferente por tipo? Simplesmente chamamos uma especialização de modelo:
Ou seja - a função a ser chamada é decidida com base no tipo. Em tempo de compilação!
Para reformular novamente:
WorkOnPixel
versões, o código C ++ será MAIS RÁPIDO que o C, porque o compilador incluirá aWorkOnPixel
especialização de modelo específico do tipo ligar!Menos código, sem sobrecarga de tempo de execução, mais segurança.
Isso significa que C ++ é o primeiro e o fim de todas as linguagens? Claro que não. Você ainda precisa medir as compensações. Pessoas ignorantes usarão C ++ quando deveriam ter escrito um script Bash / Perl / Python. Os novatos em C ++ com gatilho feliz criarão classes aninhadas profundas com herança múltipla virtual antes que você possa pará-los e enviá-los para empacotamento. Eles usarão a meta-programação complexa do Boost antes de perceber que isso não é necessário. Eles ainda usam
char*
,strcmp
e macros, em vez destd::string
e modelos.Mas isso não diz nada mais do que ... observe com quem você trabalha. Não há linguagem para protegê-lo de usuários incompetentes (não, nem mesmo Java).
Continue estudando e usando C ++ - apenas não exagere.
fonte
RAII para o bebê da vitória.
Sério, a destruição determinística no C ++ torna o código muito mais claro e seguro, sem sobrecarga.
fonte
Modelos e o STL. Você troca um pouco de tempo de construção (e algumas mensagens de erro potencialmente incompreensíveis) por muitas ferramentas úteis de abstração e economia de trabalho, sem nenhum impacto considerável no desempenho em tempo de execução (embora a pegada binária possa ser um pouco maior).
Demora um pouco para entender (demorei alguns anos antes de clicar), mas uma vez que você fizer isso, pode tornar a vida muito mais simples.
O processamento de texto em C ++ é de magnitude menos dolorosa do que em C.
fonte
Sim.
Se você está procurando eficiência executável, está em C ou C ++, então vou me concentrar nisso.
Mesmo antes dos modelos serem comuns, eu preferia usar C ++ em vez de C para os tipos de executáveis discutidos em meados da década de 90 por dois motivos muito simples: polimorfismo de objeto e RAII .
Eu usei objetos C ++ polimórficos para todos os tipos de coisas interessantes. Por exemplo, eu estava trabalhando em um sistema Linux incorporado com sobreposições de buffer de quadro nas CPUs OMAP e XScale ARM. As duas arquiteturas de hardware têm recursos de sobreposição diferentes com APIs muito diferentes. Usei uma classe base comum "Overlay" virtual para expor uma visão idealizada de sobreposições e depois escrevi as classes "OmapOverlay" e "XScaleOverlay" que foram instanciadas adequadamente no tempo de execução, dependendo da arquitetura em que o código detectou que estava sendo executado.
Para simplificar demais, RAII é a idéia de que você aloca recursos conectados a um objeto durante o construtor do objeto, ou talvez mais tarde na vida útil do objeto, e os recursos são desalocados ou liberados no destruidor do objeto. Isso é muito bom em C ++, porque objetos que são variáveis automáticas são destruídos quando ficam fora do escopo. Para alguém igualmente competente em C e C ++, é muito mais fácil evitar vazamentos de recursos e memória em C ++. Você também não vê muito código C ++ com o meme C muito comum de um rótulo no final de uma função que precede
free()
várias chamadas para , e váriosgoto
no bloco de funções pulando para lá.Estou ciente de que você pode fazer todas essas coisas com C - é apenas muito mais trabalho, muito mais linhas de código, e o que você conclui é muito mais feio e difícil de entender. Existe um código de polimorfismo em todas as partes internas do servidor X , e cara, é fugaz e estranho e frequentemente difícil de rastrear.
Também trabalho muito com tecnologias GNOME como GTK + e Clutter, todas escritas em C usando o sistema GObject. GObject é como o sistema de objetos C ++ com a boa capa removida e todas as internas feias expostas, e geralmente requer meia dúzia de linhas de código para fazer o que uma chamada de método C ++ de uma linha faria. Atualmente, estou escrevendo um pouco
ClutterActors
e, embora a matemática seja realmente interessante, estou constantemente pensando: "Isso tudo seria muito mais sucinto e compreensível em C ++".Também penso frequentemente: "Sabe, se eu estivesse escrevendo isso em C ++ em vez de C, eu estaria na sala assistindo MythBusters com minha esposa, em vez de sentar no meu escritório às 21h."
fonte
C ++ é tão rápido quanto C (algumas coisas são mais rápidas, outras mais lentas) e oferece melhores abstrações e organização. As classes funcionam de maneira semelhante aos tipos primitivos, permitindo que grandes quantidades de código sejam usadas sem serem lembradas. Sobrecarga de operador e modelos tornam possível escrever código que funciona melhor se as representações de dados mudarem. Exceções podem facilitar o tratamento de erros. O compilador pode ser usado para verificar mais coisas em tempo de compilação.
O preço que você paga por isso é uma curva de aprendizado bastante desagradável e é mais fácil cometer erros sutis do que na maioria dos outros idiomas com os quais estou familiarizado.
Portanto, não sei dizer se valeria a pena aprender o que está fazendo agora. Você certamente pode se dar bem com combinações de Python ou Perl e C, mas o C ++ oferece abstração e desempenho em um pacote difícil de se acostumar.
fonte
restrict
é usado para fazer exclusões de otimizações de alias, então como isso ajuda a tornar as coisas mais rápidas ? e o que é um "parâmetro de matriz estática"? e como o "estilo" afeta o desempenho?T (&arr)[n]
oustd::array<T, n>
- terá que pesquisar mais este, pois não há muitas informações por aí. Isso faz sentido sobre indicadores inteligentes, definitivamente um bom exemplo. Se codificássemos em igualdade de condições, não usaríamos exceções, portanto nenhum custo potencial seria incorrido ... no entanto, suspeito que você esteja fazendo alusão a como, uma vez que as bibliotecas de terceiros entrem em cena, muitas suposições Estão em risco.Considero o C ++ como uma linguagem dos anos 90, uma linguagem de uma época passada.
Naquela época, era grande porque oferecia construções e mecanismos de linguagem de nível superior a um custo menor em termos de desempenho. Foi a ferramenta universal para o desenvolvimento de tudo, desde aplicativos de catálogo de endereços a software aviônico, e que inspirou a moda do OO. OOP resolveu a fome e a AIDS e, sim, culpo o C ++ por tentar fazer uma lavagem cerebral no final dos anos 90, quando comecei a programar que qualquer linguagem que não seja OO não vale a pena aprender.
Agora que o hardware avançou muito e novas linguagens modernas apareceram, não vejo o C ++ permanecendo uma opção relevante para a maioria dos programas de aplicativos, exceto para softwares intensivos em computação, nos quais você ainda precisa de alguma abstração (jogos, simulações de física, sistemas CAD etc.) ) Até o último pode ser evitado se você escrever um mecanismo compacto e modular em C e tiver uma lógica de aplicativo de nível superior delegada a uma linguagem de script pura.
Se você precisar ir ao metal, use C sanely, e quando precisar subir de alto nível, faça-o em uma linguagem moderna que não anuncie o encapsulamento, enquanto você pode alterar livremente cada byte através de um ponteiro.
fonte
De acordo com Linus , não:
fonte
Eu não acho que exista qualquer razão convincente para usar C ++. Se você deseja fazer programação OO, pode usar o Python e escrever as partes que precisam de desempenho rápido em C.
EDIT: Existem outras linguagens que interagem bem com C, então se você não gosta de Python, existem alternativas.
fonte
Existe um motivo para usar C ++? Certamente.
Algumas pessoas podem simplesmente preferir usar C ++ em vez de outras opções. Perguntar se há uma razão para usar C ++ é como perguntar por que precisamos ter centenas de sabores de sorvete. Nem todo mundo gosta de simplesmente ficar com baunilha.
Se os desenvolvedores já são muito competentes com C ++, a pergunta para eles pode não ser 'por que usá-lo?', Mas sim 'por que não?'. Parece haver essa coisa anti-C ++ da moda acontecendo no SO agora, mas, acredite ou não, nem todo mundo concorda com isso. Algumas pessoas podem simplesmente gostar do C ++ melhor que as outras línguas.
O C ++ precisa ser usado para aplicativos? Claro que não. Mas essa mesma pergunta exata também pode ser feita para qualquer outro idioma. Existem muito poucos casos em que um idioma específico precisa ser usado para um aplicativo.
fonte
Estou apenas mudando de C para C ++ e acho que o ganho é considerável, mesmo que você não precise de modelos e OOP.
fonte
Estou surpreso que ninguém tenha mencionado isso ainda, mas o C ++ nos apresentou referências , que quase resolvem todos os problemas e armadilhas dos ponteiros:
Ao invés de:
Muito mais seguro e fácil também ... e sem a sobrecarga de passar por valor.
fonte
Onde e por que geralmente serão:
Para programação no lado do servidor, você pode escolher entre uma infinidade de idiomas diferentes, compilados ou interpretados. Geralmente, a escolha do idioma é orientada por qual plataforma você ou sua equipe serão mais eficazes. Ou, se você ainda não possui uma equipe, a disponibilidade de habilidades no mercado.
Em uma nota lateral, eu realmente não entendo decidir usar C / C ++ com base no desempenho (apenas), pois muitas linguagens de script são extensíveis com C / C ++. Você obtém o benefício de uma linguagem de desenvolvimento rápido, juntamente com a capacidade de migrar as partes lentas para extensões C / C ++. Certamente, se você está programando sistemas em que todas as operações contam, é compreensível, mas na maioria dos aplicativos não entendo.
fonte
C ++ vs Python vs Perl não podem ser julgados facilmente. Depende do projeto e dos requisitos.
O C ++ possui um arsenal de utilitários de muito tempo atrás, rodando em várias plataformas. Mas é doloroso começar a andar pelos fluxos apenas passando String para Inteiro e reverso.
C ++, por outro lado, tem um acordo terrível com dependências em bibliotecas. Depois de compilar algo no GCC X ou VC ++ Y, não é possível confiar que o código será executado na próxima versão dessas ferramentas. O mesmo inferno está no Windows, o mesmo inferno está no Unix também.
Perl, tira seu poder do mundo Unix, mas especialmente como uma ferramenta de expressão regular. É isso que é usado na maioria das vezes. Juntamente com algumas ferramentas bastante sérias que nem mesmo o Java pode fazer de maneira normal (veja como fazer upload de um arquivo para um servidor web), o Perl é "just do it".
Python é fácil, flexível e uma linguagem dinâmica. Tão fácil que você pode enviar um número inteiro para uma função, o script espera string, mas você pode obter um resultado! Inesperado, mas um resultado. Portanto, o programador precisa ser muito cauteloso. O IDLE oferece alguma depuração, mas quando você faz o TELNET em um sistema ou o SSH em três níveis abaixo e deseja encontrar seu problema, o depurador não estará lá para ficar ao seu lado. Mas, ele pode fazer um ótimo trabalho matemático rapidamente.
Java é um ecossistema de chavões, tecnologias alienígenas e grandes palavras e quando você deseja fazer upload de um arquivo no servidor da Web, descobre que pode fazê-lo apenas se o servidor tiver JSP . Se você deseja chamar as bibliotecas do sistema ou as funções do sistema, como o monitoramento, descobre que precisa cavar muito. E talvez para alcançar JNI e OK ... você pensa então ... "Por que, Senhor?"
Além disso, o Java é uma ótima ferramenta para suítes de negócios e multithreading, gostei muito.
Rápido para criar um programa e mostrar ao seu currículo "Ah, eu também conheço essa tecnologia" e seu futuro patrão, surpreenda-se! Mesmo assim, a tecnologia pode não ser a necessária ... (OK, pessoal, eu odeio o Spring Framework ....)
fonte
O que você deve ter em mente ao escolher um idioma é qual o benefício que você terá ao usá-lo e quanto tempo levará para obtê-lo.
A principal idéia entre linguagens como python e perl é fazer mais com menos tempo de homem, mas com mais tempo de CPU. De fato, você gastará mais tempo codificando um script python ou perl do que ele será executado, mas você entendeu.
A vantagem do C / C ++ é que eles são rápidos, mas com um custo de sintaxe e de digitação forte: você precisa fazer muitas coisas para que o computador não precise escolhê-lo em tempo de compilação.
Quando você cria um código, algumas linhas são executadas muito mais do que outras, e essas são as que apresentam um problema. Por outro lado, todo o restante do código, aquele em que você passou muito tempo, é executado com muito menos frequência. Você pode ter ouvido, mas é a infame regra 80/20 e não poderá contornar essa regra.
A solução para esse problema é usar uma linguagem mais fácil (por mais fácil, quero dizer mais amigável ao desenvolvedor: menos digitação, interpretação lenta, muitas rotinas e coisas pré-existentes, etc.) para fazer todo o seu código.
Você fará isso rapidamente, se comparado com C ou C ++, seria necessário muito mais dor de cabeça.
Seu programa será lento, mas com um criador de perfil, você isola a parte executada 80% das vezes e com C ou C ++.
Ao programar dessa maneira, você economizou muito tempo e seu programa é tão eficiente quanto rápido, tem muito menos chances de vazar memória e você economizou tempo.
As linguagens de script foram projetadas para ficar do lado do desenvolvedor, mas a otimização ainda é possível. É claro que você pode ser um mágico de padrões de design ou um vodu da STL ou mesmo um guerreiro cigano, e talvez um monge haskell. Mas idiomas nos fazem falar com computadores, idiomas não são feitos para sermos computadores!
fonte
Linux? E quanto a "Pascal orientado a objetos" ou "D"?
Sugestões:
fonte
O C ++ que eu uso é chamado C com classes!
fonte
Na verdade, há uma resposta única para todas as perguntas formadas dessa maneira. A melhor razão para usar a tecnologia X em vez da tecnologia Y (onde X e Y estão aproximadamente no mesmo nível (como quase todas as linguagens de programação contemporâneas)] é porque você já conhece X e não conhece Y.
(mas depois que Haskell chegou, não havia mais motivo para usar outra coisa)
fonte
Não, não mesmo. Se você não precisar do desempenho e houver uma biblioteca, poderá usar o outro idioma, então não se preocupe com o C / C ++. Só o faço hoje em dia quando viso sistemas embarcados que não podem (facilmente?) Executar idiomas. Às vezes eu uso C porque estou escrevendo um plugin, mas realmente não.
No entanto, eu não usaria Python, Perl etc. para evitar o C. Minha preferência é realmente C #, porque gosto de uma boa biblioteca (que é uma força do .NET) e gosto de linguagens de tipo estaticamente. Boo é uma boa alternativa. Mas realmente Haskell , OCaml , D , ML e outros estão bem.
fonte