O WG21 possui um cronograma rígido (consulte a
P1000 ) para liberação padrão a cada três anos. E sem atrasos.
Durante cada ciclo, recebemos regularmente perguntas “Por que isso é tão rigoroso?”, Especialmente de novos membros do comitê que não estão familiarizados com a sua história e as razões do estado atual das coisas. E durante uma teleconferência preliminar com o governo de Colônia, várias pessoas recomendaram descrever por que estávamos fazendo isso e como foi tomada a decisão de adotar esse cronograma.
Pintei tudo isso na forma de perguntas e respostas para o próximo rascunho do P1000 e enviei uma cópia aos membros do comitê a caminho de Colônia. Este material será publicado na próxima versão pública do P1000; enviaremos em algumas semanas a partir do momento atual.
No entanto, o rascunho das perguntas frequentes pode ser de interesse do público, por isso ofereço uma cópia dele. Espero que, na maioria das vezes, seja útil para você, esclarecer de alguma forma e talvez até divertir um pouco.
Existem erros no padrão, você deve adiar o C ++ 20?
Claro que sim e não.
Estamos nos movendo em uma determinada direção na velocidade escolhida: as correções estão planejadas para este ano passado, portanto a programação no início do C ++ “19” (Kona) estabelece um prazo para interromper a adição de recursos (congelamento de recursos) no C ++ “20”, para que tivemos um ano para corrigir bugs, inclusive trabalhando com comentários de diferentes países neste verão. Antes do início de 2020 (reuniões em Colônia, Belfast e Praga), devemos fornecer feedback e aplicar outras soluções para os problemas, bem como correções de bugs.
Se tivermos mais uma ou duas reuniões, podemos adicionar um <nome do recurso>, que está quase pronto, então você deve adiar o C ++ 20?
Claro que sim e não.
Aguarde mais algumas reuniões (depois de Praga), e o C ++ 23 estará aberto para negócios, e antes de tudo votaremos em adicionar <nome do recurso> ao rascunho de trabalho do C ++ 23. Foi o que fizemos com os conceitos: eles não estavam prontos para a transição do TS diretamente para o C ++ 17. Portanto, na primeira reunião do C ++ 20 (em Toronto), eles votaram na transferência da funcionalidade básica dos conceitos para o rascunho do C ++ 20, que deu muito tempo para melhorar e refinar o restante da parte contraditória do TS (sintaxe não-modelo), introduzida ano que vem (San Diego). Agora toda a funcionalidade está pronta.
Isso parece ser muito rigoroso. Por que liberar versões IS em intervalos fixos (três anos)?
Como no caso do lançamento do C ++ IS, essa é uma das duas principais opções para gerenciamento de projetos, e a experiência mostra que essa opção é melhor que a segunda.
Quais são as duas opções para gerenciamento de projetos para o lançamento do C ++ IS?
Que bom que você perguntou.
No caso de uma liberação, há duas opções principais: escolha um recurso ou uma data de liberação e, quando você seleciona uma, perde o controle sobre a definição da outra. Você não pode controlar os dois simultaneamente. Em resumo:
Eu explico:
(1) “O quê”: selecionamos recursos e enviamos como prontos, sem necessidade de escolher um horário de lançamento . Se você precisar de mais tempo para finalizar um recurso do rascunho do padrão, o mundo inteiro terá que esperar por você. Você trabalha em grandes recursos que requerem vários anos de desenvolvimento e tenta parar de trabalhar em novos recursos enquanto estabiliza o lançamento.
O mesmo ocorreu com o C ++ 98 (era esperado por volta de 1994, Björn disse que, se o lançamento não fosse lançado, seria um fracasso) com o C ++ 11 (chamado 0x porque x era esperado em 2007 ) Essa é uma abordagem “deixe o paciente sem proteção” por um período indeterminado, o que levou a um atraso nos testes e na liberação da integração. E isso, por sua vez, levou a uma grande incerteza no mercado em relação ao momento do próximo padrão e se ele será lançado (sim, não apenas os participantes do desenvolvimento, mas mesmo alguns membros do comitê duvidaram seriamente em 1996 e 2009). existem lançamentos relevantes). Por vários anos, a maioria dos compiladores não atendeu ao padrão, porque ninguém sabia quantas mudanças incompatíveis o comitê lançaria no novo lançamento ou quando seria esperado? Isso levou a uma ampla variedade e fragmentação do suporte a C ++ nos compiladores disponíveis para a comunidade.
Por que fizemos isso, somos idiotas? Na verdade, eles eram inexperientes e ... digamos "otimistas". Era uma estrada pavimentada com as melhores intenções. Em 1994-1996 e em 2007-2009, acreditávamos realmente que agora promoveríamos mais uma, duas ou três reuniões e faríamos tudo, e cada vez que elas seriam adiadas por até quatro anos. E agora eles viram por sua própria experiência que não pode haver transferência por um ano ou dois.
Felizmente, tudo mudou graças à opção (2).
(2) “Quando”: selecionamos a data de lançamento e enviamos os recursos que estão prontos, você não precisa selecionar um conjunto de recursos . Se for necessário mais tempo para refinar um recurso de um rascunho de padrão, nós o descartamos e enviamos o que está pronto. Você pode continuar trabalhando em grandes recursos, cuja criação leva tempo como em várias versões, mas em "ramificações" de terceiros, adicionando-as à ramificação mestre do IS assim que possível. E você trabalha constantemente nos recursos, porque o desenvolvimento deles é completamente separado da versão atual (não há grande ponto de conexão).
Nós aderimos a essa abordagem desde 2012 e não queremos abandoná-la. Essa é a abordagem de "remendar regularmente o paciente", que leva à expectativa de maior qualidade devido às integrações regulares forçadas e à recusa de adicionar trabalho ao rascunho do SI até que ele atinja um certo nível de estabilidade, geralmente dentro do ramo de recursos. Também cria um ciclo de liberação previsível em que o mercado pode confiar. Ao longo dos anos, os autores dos compiladores começaram cada vez mais cedo, após o próximo lançamento, a lançar versões de seus produtos em conformidade com o padrão, o que nunca havia acontecido antes. E em 2020, esperamos o lançamento de implementações totalmente compatíveis em um ano com o lançamento do padrão, o que também nunca aconteceu antes. Isso é apenas para o benefício de todo o mercado - desenvolvedores, usuários, professores.
Observe também que, desde que começamos a aderir a essa abordagem, começamos a fazer mais (se medido por recursos grandes, médios e pequenos) e com maior qualidade (se medido por uma redução rigorosa no número de relatórios de bugs e comentários sobre rascunhos de cada norma). Apesar de enviarmos o que conseguimos preparar (e se não conseguimos algo, não enviamos).
Você está falando sério sobre a abordagem (2)? Se, de acordo com um membro autoritário do comitê, algum grande recurso estiver "quase pronto", você ficará tentado a esperar um pouco, certo?
Muito a sério, e não.
Temos estatísticas: em 2016 em Jacksonville, quando finalmente decidimos os recursos do C ++ 17, Björn Straustrup falou em uma reunião plenária com uma proposta para incluir conceitos no C ++ 17. Quando nenhum consenso foi alcançado, foi perguntado diretamente a Straustrup se ele queria adiar o lançamento do C ++ 17 por um ano para incluir conceitos nele. Björn respondeu "não" sem hesitação e evasão e acrescentou que o C ++ 17 sem conceitos era mais importante que o C ++ 18 ou o C ++ 19 com conceitos, embora a Straustrup os trabalhasse há cerca de 15 anos. A escolha foi a seguinte: (2) lançamos o C ++ 17 sem conceitos e depois o C ++ 20 com os conceitos (o que fizemos), ou (1) renomeamos o C ++ 17 para C ++ 20, que é isomórfico (2) com exceção de pular o C ++ 17 e recusar-se a liberar o que já estava pronto para o C ++ 17.
E a troca entre (1) e (2)? Digamos, geralmente aderimos a (2), mas com "pouca" flexibilidade em termos de "um pouco" de tempo extra, se você precisar refinar o recurso?
Não, porque acontece (1).
Fred Brooks, no
The Mythical Man-Month, explicou popularmente “a pequena transferência mítica” e concluiu: “
Não permita nenhuma transferência pequena ”.
Imagine que portamos o C ++ 20. Teríamos que voltar de (2) a (1), por mais que tentássemos evitá-lo e, ao mesmo tempo, não receberíamos nenhum benefício. Se decidíssemos adiar o C ++ 20 para aperfeiçoá-lo, adiaríamos o padrão por pelo menos dois anos. Não existem conceitos como a transferência de uma ou três reuniões, porque durante esse período outros continuarão (razoavelmente) a dizer: "Bem, meu recurso precisa apenas de mais uma reunião, ainda a remarcamos, vamos transferir outra". E se transferirmos pelo menos dois anos, isso significa que o C ++ 20 se torna C ++ 22 e provavelmente C ++ 23 ... mas já vamos enviar o C ++ 23! - Ou seja, em qualquer caso, enviaremos o C ++ 23, e a única diferença é que
não transferimos o C ++ 20 com uma grande quantidade de trabalho realizado, pronto para o lançamento, e não fazemos o mundo inteiro esperar mais três anos. O atraso não beneficiará esses recursos, a maioria deles ou todos juntos.
Portanto, a frase é equivalente a "vamos transformar C ++ 20 em C ++ 22 ou C ++ 23" e a resposta simples: "sim, teremos C ++ 23, mas além de C ++ 20, e não em seu lugar. " Um atraso no C ++ 20 significa pular o C ++ 20 em vez de liberar um produto final bom, estável e estável, e não haverá benefício disso.
Mas o recurso X está quebrado / leva mais tempo do que resta para corrigir bugs no C ++ 20!
Nenhuma pergunta! Nós podemos simplesmente cortá-lo.
Nesse caso, alguém precisará escrever uma carta em EWG ou LEWG (dependendo da situação) com uma descrição da situação e oferecer a remoção do recurso do rascunho de IS. Esses grupos considerarão a apelação e, se decidirem que o recurso está quebrado (e o plenário concordar com eles), o recurso será adiado para a próxima versão do C ++. Já fizemos isso com os conceitos de C ++ 0x.
Mas no caso de (1), transferiremos não apenas esse recurso, mas
todo o conjunto de recursos de C ++ 20 para C ++ 23! Isso seria ... busto.
A abordagem (2) significa lançamentos "principais / secundários"?
Não. No começo, dissemos isso até percebermos que (2) significa apenas que você não precisa escolher um conjunto de recursos, mesmo do ponto de vista da versão "principal / secundária".
A abordagem (2) significa apenas "enviamos o que está pronto". Lançamentos são obtidos:
- o mesmo tamanho (ou seja, geralmente médio) dos recursos é "menor" porque menos tempo é gasto em seu desenvolvimento (digamos, menos de três anos cada) e, em geral, obtemos o mesmo número de recursos concluídos no lançamento;
- e um tamanho variável (não é necessário uma ou duas vezes) para os recursos "maiores", que levam mais tempo (digamos, mais de três anos cada), e cada versão do IS inclui tantos desses recursos quanto eles conseguem concluir para a versão. Portanto, em alguns lançamentos há mais, em outros menos.
C ++ 14 e C ++ 17 eram relativamente pequenos, porque muito esforço de padronização foi gasto em recursos de longa execução descritos nas propostas de implementação (por exemplo, contratos) e "ramificações de recursos" no TS (por exemplo, conceitos).
C ++ 20 é um ótimo lançamento ...
Sim O C ++ 20 possui muitos recursos principais. Três dos maiores começam com “ko” (conceitos, contratos, corotinas), então podemos chamá-lo de co_cpp20. Ou co_dependente.
... e não é muito feito no ciclo de três anos para C ++ 20?
Não, veja acima "uma vez por vez não é necessário".
O C ++ 20 é grande, não porque fizemos mais em três anos, mas porque há muitos desenvolvimentos longos (incluindo pelo menos dois nos quais estamos trabalhando no formulário atual desde 2012 na forma de frases P e TS) ) atingiram o estágio de prontidão e decidiram incluí-los no rascunho de IS da mesma versão.
Quase sempre, os principais recursos são desenvolvidos por muitos anos. A principal diferença entre a abordagem (1) para C ++ 98 e C ++ 11 e a abordagem (2) é que, em C ++ 98 e C ++ 11, o lançamento foi adiado até que todos esses recursos estivessem prontos, e agora enviamos grandes assim que estiver pronto, e junto com eles lançaremos muito mais.
O C ++ 20 passou pelo mesmo ciclo de três anos que o C ++ 14 e o C ++ 17. Não fizemos mais nos últimos três anos do que nos dois ciclos anteriores, apenas acrescentamos mais aos principais recursos. Se algum deles não estivesse pronto, já o teríamos descartado e já terminado para o C ++ 23. Se isso acontecer, reportaremos isso na proposta de implementação e explicaremos os motivos.
C ++ 14 + 17 + 20 compôs nosso terceiro ciclo de nove anos (2011-2020) após C ++ 98 (1989-1998) e C ++ 11 (2002-2011). Mas desde que aderimos à abordagem (2),
também lançamos desenvolvimentos prontos para o final dos ciclos de três e seis anos.
Não é melhor detectar bugs quando um produto está em desenvolvimento e não depois que ele é lançado?
Claro que é melhor.
Mas se estivermos falando sobre os motivos do atraso no lançamento do padrão C ++, essa pergunta implica duas suposições falsas:
- que antes do lançamento do padrão, os recursos não saíam e não eram usados (muitos já têm experiência em produção);
- e que todos os recursos possam ser usados juntos até que o padrão seja lançado (não permitido).
Eu explico:
- A maioria dos principais recursos do C ++ 20 foi implementada da forma em que são refletidos no rascunho atual do padrão em pelo menos um compilador e, na maioria dos casos, já foram usados no código de produção (ou seja, já estão disponíveis para usuários muito satisfeitos) . Por exemplo, as corotinas (introduzidas apenas cinco meses antes deste artigo) foram usadas por dois anos em produção na MSVC e um ano na Clang, que ficou muito satisfeito com os grandes clientes (por exemplo, Azure e Facebook).
- Não vamos encontrar muitos problemas de interação entre os recursos até que os usuários comecem a usá-los na produção, ou seja, antes do lançamento do padrão, porque muitos desenvolvedores esperam que ele seja lançado para implementar projetos diferentes. E se mostrarmos incerteza sobre o momento do lançamento, essas implementações também serão atrasadas. Bem, eles ainda implementam algo, mas muito será pausado até que os desenvolvedores tenham certeza de que estamos prontos para o lançamento. Pergunte aos criadores do <nome do compilador favorito> o que aconteceu quando eles implementaram o <nome do recurso grande> antes de aparecer no padrão publicado. Em muitos casos, é necessário implementar repetidamente e interromper os consumidores repetidamente. Portanto, os desenvolvedores preferem esperar o comitê aprovar determinados recursos.
Por fim, não se esqueça do problema dos recursos de interação. Nós não apenas as liberamos quando estamos prontos, depois disso ainda precisamos de tempo para procurar problemas de interação entre os recursos e adicionar suporte para essas interações, o que simplesmente não conseguimos descobrir antes que os novos recursos sejam amplamente utilizados. E não importa o quanto adiamos o lançamento do padrão, sempre haverá interações que poderemos explorar apenas muito mais tarde. Você precisa gerenciar esse risco com a ajuda do design flexível, garantindo a compatibilidade dos recursos, e não espere para se livrar de todos os riscos.
O padrão nunca será perfeito ... você não libera bugs?
Sim
Se percebermos que o recurso não está pronto, devemos removê-lo do lançamento.
Se percebermos que um recurso pode ser melhor e sabemos que a mudança pode ser compatível com versões anteriores, esse não é um motivo para recusar seu lançamento agora. Ele pode ser lançado como uma extensão no C ++ a seguir.
Intencionalmente, lançamos recursos que planejamos melhorar no futuro, enquanto estamos confiantes de que podemos manter a compatibilidade com versões anteriores.
Mas você não deve tentar minimizar os erros de liberação?
Sim Estamos tentando.
Mas não tentamos evitar todos os riscos. Há também um risco e (possível) preço de se recusar a liberar o que parece pronto para nós. E mais frequentemente do que não, estamos certos.
Tem certeza de que agora a qualidade é melhor do que usar a abordagem (1)?
Sim
De acordo com as métricas objetivas, o volume de comentários de diferentes países e os relatórios de erros, C ++ 14 e C ++ 17 foram nossos lançamentos mais estáveis e, por essas métricas, foram 3-4 vezes maiores que C ++ 98 e C ++ 11. E o motivo está justamente na regularidade dos lançamentos, na colocação de grandes recursos em primeiro lugar nos ramos TS (incluindo descrições completas de sua integração com o padrão principal) e na infusão subsequente, quando estamos convencidos da disponibilidade.
Desde 2012, o padrão principal
sempre foi mantido em um estado quase pronto para o envio (portanto, até rascunhos de rascunhos da mesma alta qualidade que os lançamentos dos padrões C ++ 98 e C ++ 11). Isso nunca aconteceu antes, quando mantivemos o paciente inseguro por um longo tempo, com longas listas de problemas e órgãos espalhados, os quais vamos colocar em breve. Agora sabemos que podemos manter um cronograma com trabalho de alta qualidade, porque sempre permanecemos em um estado de prontidão para liberação. Se preferir, você pode lançar um CD agora mesmo, sem se reunir em Colônia, e ainda assim a qualidade seria muito maior do que nunca com um CD C ++ 98 ou C ++ 11 (na verdade, e seus padrões publicados) . E considerando que C ++ 98 e C ++ 11 foram bem-sucedidos, o entendimento de que agora a qualidade é ainda mais alta significa que estamos no caminho certo.
C ++ 98 e C ++ 11 foram desenvolvidos por cerca de 9 anos e eram produtos muito bons ...
Sim: 1989-1998 e 2002-2011.
... e C ++ 14 e C ++ 17 foram lançamentos menores. O C ++ 20 é uma versão importante?
Repito, acredito que é correto comparar C ++ 14 + 17 + 20 como um todo: este é o nosso ciclo de nove anos, mas desde que aderimos à abordagem (2), também lançamos os desenvolvimentos que estavam prontos para concluir os ciclos de três e seis anos. .
A abordagem (2) permite atingir objetivos baseados em recursos como P0592 para o próximo C ++?
Claro! Embora não haja palavras como "deve incluir esses recursos", porque será a abordagem (1).
Lutar por um determinado conjunto de recursos e dar prioridade a um deles é normal, mas é uma questão de prioridade. Até o momento, pegaremos apenas o que está pronto, mas podemos escolher o que trabalhar antes de tudo, a fim de nos preparar o mais rápido possível.