Recursos de C ++ para "toda a equipe"?

16

No C ++, recursos como exceções afetam todo o programa: você pode desabilitá-los em todo o programa ou precisa lidar com eles em todo o código. Como um artigo famoso no C ++ Report coloca:

Contra-intuitivamente, a parte mais difícil das exceções de codificação não são os lançamentos e capturas explícitos. A parte realmente difícil de usar exceções é escrever todo o código intermediário de forma que uma exceção arbitrária possa se propagar do site de lançamento para o manipulador, chegando com segurança e sem danificar outras partes do programa ao longo do caminho.

Como até newlança exceções, todas as funções precisam fornecer segurança básica contra exceções - a menos que apenas chame funções que garantam a exceção - a menos que você desative completamente as exceções em todo o projeto .

Portanto, as exceções são um recurso de "programa inteiro" ou "equipe inteira", pois devem ser entendidas por todos em uma equipe que as utiliza. Mas nem todos os recursos do C ++ são assim, tanto quanto eu sei.

Um exemplo possível é que, se eu não conseguir modelos, mas não os usar, ainda poderei escrever C ++ correto - ou não? Posso até chamar sortuma matriz de números inteiros e aproveitar sua incrível vantagem de velocidade. C's qsort(porque nenhum ponteiro de função é chamado), sem arriscar bugs - ou não? Parece que os modelos não são "toda a equipe".

Existem outros recursos do C ++ que afetam o código que não os usa diretamente e, portanto, são "equipe inteira"? Estou especialmente interessado em recursos que não estão presentes em C.

Atualização : estou procurando especialmente recursos em que não há sinal imposto pelo idioma que você precisa conhecer. A primeira resposta que eu mencionei const-correção, que também é toda a equipe, portanto todos precisam aprender sobre isso; no entanto, o AFAICS afetará você apenas se você chamar uma função que está marcada const, e o compilador impedirá que você a chame em objetos não-const, para que você obtenha algo para o Google. Com exceções, você nem entende; além disso, eles sempre são usados ​​assim que você usa new, portanto as exceções são mais "insidiosas". Como não posso expressar isso de maneira objetiva, aprecio qualquer recurso de toda a equipe.

Atualização 2 : em vez do recurso C ++, eu deveria ter escrito algo como "recurso específico do C ++", para excluir itens como multithreading que se aplicam a uma grande quantidade de linguagens de programação convencionais.

Apêndice: Por que essa pergunta é objetiva (se você se pergunta)

O C ++ é uma linguagem complexa; muitos projetos ou guias de codificação tentam selecionar recursos "simples" do C ++, e muitas pessoas tentam incluir ou excluir alguns de acordo com critérios subjetivos. Perguntas sobre esse assunto são regularmente encerradas com regularidade aqui no SO.

Acima, em vez disso, eu defini (o mais precisamente possível) o que é um recurso de linguagem de "equipe inteira", forneço um exemplo (exceções), juntamente com extensa evidência de suporte na literatura sobre C ++, e solicito recursos de equipe inteira em C ++ além de exceções.

Se você deve usar os recursos de "equipe inteira" ou se esse é um conceito relevante, pode ser subjetivo - mas isso significa apenas que a importância dessa questão é subjetiva, como sempre.

Blaisorblade
fonte

Respostas:

11

Eu indicaria a simultaneidade como um recurso de 'equipe inteira'.

Embora seja possível projetar o software de modo que apenas alguns especialistas precisem estar cientes dos problemas de simultaneidade e o restante da equipe possa colher os benefícios sem se preocupar com as complexidades (como você pode fazer com os modelos), na prática ele faz isso. não funciona dessa maneira. Na prática, se você tiver vários encadeamentos, precisará analisar cuidadosamente cada variável que usar, se houver problemas de simultaneidade em potencial com esse uso.

Bart van Ingen Schenau
fonte
Concordo que os threads são recursos de toda a equipe, embora não sejam específicos de C ++. No entanto, também existem outras interfaces para concorrência (não baseadas em encadeamento), principalmente em outros idiomas, e algumas permitem que a concorrência seja muito melhor encapsulada (embora esse ainda seja um tópico de pesquisa atual em linguagens de programação). Portanto, é uma questão em aberto se isso se aplica à concorrência em si.
Bluesorblade 27/10/2013
@ Blaisorblade - C ++ 11 introduziu sua própria biblioteca de threads, então sim, agora faz parte do C ++.
Michael Kohne 31/10
@ MichaelKohne: Eu não afirmei que o C ++ não suporta multithreading. Eu disse que os threads não são específicos de C ++, porque muitas outras linguagens os possuem. Acabei de observar que os problemas descritos se aplicam aos threads como uma interface para simultaneidade.
Bluesorblade #
Eu diria que "condição de corrida" é uma palavra melhor para esta questão central. Ou seja, os programadores podem não precisar trabalhar ou usar a estrutura de simultaneidade, mas se escreverem algum código C ++ e seu código puder ser chamado potencialmente a partir de mais de um encadeamento, será necessário pensar nas condições de corrida em geral, em todo o código escrito.
Rwong
Isso me lembra de uma falta de comunicação com um colega de trabalho que aconteceu anos atrás. Um colega de trabalho perguntou a outro colega de trabalho: isso (alguma função) é seguro para threads? O outro colega respondeu que sim. O colega de trabalho que pediu então passou a usá-lo a partir de vários encadeamentos e obteve resultados inesperados (não travou, mas várias operações foram aplicadas no mesmo objeto). O colega de trabalho que perguntou não teve o modelo mental do que significa "thread-safe" e confundiu a resposta como "eu posso fazer o que quiser".
Rwong #
10

A resposta óbvia é a constcorreção: uma vez que const/ volatilequalification é infecciosa, uma vez que uma parte do código começou a usá-lo, todo código de chamada (direta ou indiretamente) também deve estar constcorreto ou rejeitar constexplicitamente.

Como com exceções, no entanto, isso é obviamente uma coisa boa . Mais ainda, porque ao contrário da segurança das exceções, é rigorosamente verificado pelo compilador.

Konrad Rudolph
fonte
2
Além disso, const-correctness é transparente: é apenas sobre o tipo que você atribui a uma função (que é sempre visível) e o compilador gritará com você se você errar. Eu estava pensando em coisas mais opacas, nas quais você não tem idéia de que algo está errado até que seja tarde demais (e mesmo assim, será difícil descobrir isso). Mas sua resposta é interessante de qualquer maneira, portanto votada.
Bluesorblade 26/10/2013
10

Ponteiros.

  • O ponteiro aponta para a memória na pilha?
  • O ponteiro aponta para a memória na pilha?
  • O ponteiro aponta para um único objeto?
  • O ponteiro aponta para uma matriz?
  • O ponteiro aponta para um local no meio de uma matriz?
  • O ponteiro é válido?
  • O ponteiro está mutilado?
  • Qual código "possui" o ponteiro?
  • O objeto referenciado deve ser desalocado manualmente? Se sim, como?
Thomas Eding
fonte
1
+1 especificamente por causa da pergunta sobre a propriedade do ponteiro. Sem indicadores inteligentes, a propriedade realmente se propaga por toda a equipe.
JKor #
3

Outra possibilidade é a sobrecarga do operador. Uma vez que uma parte da base de código começa a mexer com operadores sobrecarregados, todos tendem a começar a adivinhar exatamente o que exatamente qualquer objeto com o qual estão trabalhando está realmente fazendo. Ele não se propaga explicitamente pela base de código da mesma maneira que as exceções e a correção constante, mas é definitivamente algo que pode começar a causar problemas se toda a equipe não estiver na mesma página sobre quando, como e por que usá-lo.

Evicatos
fonte
1

O único além da correção const (vista acima) que vem à mente é o estado de fluxo (ing). Se você escrever código C ++ em que você usa objetos e subobjetos e hierarquias de objetos, é possível que você envie ou receba dados de / para o operador do programa. Você pode escrever operações simples de streaming que serão compiladas e serão semanticamente corretas ...

std::ostream& operator<< (std::ostream&, MyClass const&) {...}
std::istream& operator>> (std::istream&, MyClass&) {...}

... Mas, uma vez que você o faça, nunca terá garantia de que o que você está tentando escrever (ou mais importante, ler) segue o mesmo formato que o cliente está enviando. Existem muitos casos de estranheza acontecendo com fluxos, ainda pior se você tiver que passar fluxos ou sinalizadores de fluxo como argumentos em sua cadeia de chamadas de funções ... que é o que geralmente é implementado no fluxo de classes. Portanto, o streaming pode ser definido como "insidioso", como você usou o termo acima, ou talvez até como "viral" ( embora não em nenhum lugar do mesmo grau que a correção constante ).

Tem um membro no fundo da sua hierarquia de classe que é um string? Surpresa, o cliente envia melhor uma única palavra, ou então. Você tem alguns números que deseja serializar? É melhor verificar, salvar e restaurar os sinalizadores de fluxo a cada profundidade de chamada de função, porque você nunca sabe quem é o idiota que acabou de definir seu fluxo na saída octal antes de chamar sua função. Ou pior - que acabou de chamar algo como setfille, setwportanto, interrompeu a formatação de entrada / saída do seu primeiro - e somente do seu primeiro membro integral, porque esses estados não se propagam . Ah, e não vamos perguntar sobre fluxos e internacionalização.

Não há nenhum aviso no idioma alguma de que você está fluindo da maneira certa ou da maneira errada, ou mesmo de streaming em tudo . Solicitou o código do cliente para transmitir um fluxo para gravar o backup de dados? Você realmente não tem como saber para onde o fluxo aponta /dev/null. ( Por outro lado, você pode reivindicar velocidades incríveis de backup e taxas de compressão dessa maneira! )

Luis Machuca
fonte