Suporte a C++ moderno no DCMTK
Por padrão, o DCMTK é compilado com suporte a C++11 habilitado (via CMAKE_CXX_STANDARD definido como 11). Isso geralmente aumenta o desempenho, pois algumas operações podem ser realizadas de forma mais eficiente, por exemplo, utilizando a semântica de movimento.
Normas C++ posteriores podem ser habilitadas usando a configuração CMAKE_CXX_STANDARD. O arquivo INSTALL do DCMTK descreve as versões da norma C++ disponíveis que são conhecidas por funcionar para a versão do DCMTK em questão.
O DCMTK ainda pode ser compilado com um compilador C++98. No entanto, o suporte a C++98 será descontinuado no futuro.
Classes STL do C++11
Embora alguns recursos, como a semântica de movimento, sejam habilitados automaticamente em código legado ao compilar com C++11 habilitado, classes STL modernas do C++, como std::unique_ptr, precisam ser usadas explicitamente.
Como o DCMTK (ainda) não exige um compilador compatível com C++11, o toolkit vem com algumas classes wrapper para alguns desses recursos da STL. Cada classe wrapper ou mapeia diretamente para o respectivo recurso do C++11 (se disponível, veja abaixo), ou então implementa uma solução alternativa em C++98. Por exemplo, as seguintes classes STL do C++11 são implementadas dessa forma:
- std::unique_ptr (OFunique_ptr no DCMTK)
- std::shared_ptr (OFshared_ptr no DCMTK)
- std::numeric_limits (OFnumeric_limits no DCMTK)
- std::tuple (OFtuple no DCMTK)
- std::error_code (OFerror_code no DCMTK)
Se você quiser garantir que o DCMTK use as versões STL dessas classes, há um sinalizador adicional (além de habilitar a versão do C++ correspondente) a ser definido durante a configuração do CMake:
Habilitar o sinalizador DCMTK_ENABLE_STL garante que, sempre que possível (ou seja, quando o compilador for compatível corretamente), a versão STL de uma classe seja preferida em vez da implementação alternativa.
Existem vários outros sinalizadores para ajustar esse comportamento com precisão:
- DCMTK_ENABLE_STL_MEMORY: pode ser usado para habilitar std::unique_ptr e classes relacionadas.
- DCMTK_ENABLE_STL_MAP: pode ser usado para habilitar std::map.
- DCMTK_ENABLE_STL_...: há outros sinalizadores para recursos específicos da STL. Eles podem ser facilmente identificados pelo prefixo.
Por padrão, esses sinalizadores são definidos como "INFERRED", o que significa que eles assumem a configuração de DCMTK_ENABLE_STL. No entanto, se você quiser apenas habilitar ou desabilitar determinados recursos (ou seja, divergir de DCMTK_ENABLE_STL), pode definir cada um deles explicitamente como "ON" ou "OFF".
Usando o DCMTK com C++11
Ao compilar com C++11 ou posterior e habilitar a STL, você obtém as seguintes vantagens:
- O DCMTK pode usar os recursos disponíveis do C++11 em vez de suas próprias implementações legadas. Estes são provavelmente mais eficientes e completos.
- A habilitação do C++11 passa a fazer parte da configuração do DCMTK, o que permite que o DCMTK o ajude a verificar a (in)compatibilidade de API/ABI entre builds com C++11 e sem C++11.
Tentar incluir um build do DCMTK com C++11 habilitado a partir de um ambiente sem C++11 resultará na seguinte mensagem de erro:
DCMTK was configured to use C++11 features, but your compiler does not or was
not configured to provide them.
Para reduzir a complexidade da implementação do DCMTK, o C++11 só deve ser usado se o seu compilador estiver em conformidade bem próxima com a norma C++11. Até onde sabemos, isso atualmente é verdade para os seguintes compiladores:
- GNU C++ Compiler (g++) versão 4.8.1 ou posterior.
- Clang (clang++) versão 3.3 ou posterior.
- De acordo com a documentação da Microsoft, Visual Studio 2019 versão 16.8 (ou superior) com Windows SDK 10.0.20348.0 versão 2104 (ou superior). O DCMTK já permite habilitar o C++11 para o VS 2017, que segundo relatos também funciona bem.
Ao compilar com C++11 ou posterior, o CMake então realiza verificações básicas para garantir que o compilador esteja configurado corretamente e esteja em conformidade próxima o suficiente com todas as normas C++ modernas até a versão da norma selecionada.
Abaixo está uma saída do CMake ao definir (com sucesso) CMAKE_CXX_STANDARD como 14:
...
-- Checking whether the compiler supports C++11
-- Checking whether the compiler supports C++11 -- yes
-- Checking whether the compiler supports C++14
-- Checking whether the compiler supports C++14 -- yes
...
GNU Autoconf
Nossa configuração do GNU Autoconf reconhece as opções --enable-cxx11 e --disable-cxx11, que podem ser usadas para configurar o DCMTK a fim de usar os recursos do C++11. Se você executar
configure --enable-cxx11
nosso script Autoconf tentará determinar os sinalizadores de compilador necessários para habilitar os recursos do C++11 (se houver algum) e executará testes de configuração para garantir que o compilador esteja em conformidade próxima o suficiente com a norma C++11. Se tudo funcionar, você obterá uma saída semelhante a esta:
checking whether to enable C++11 support...
checking whether c++ supports C++11 features by default... no
checking whether c++ supports C++11 features with -std=c++11... yes
checking whether to enable C++11 support... yes
Caso contrário, os recursos do C++11 permanecerão desabilitados, com uma saída como esta:
checking whether to enable C++11 support...
checking whether c++ supports C++11 features by default... no
checking whether c++ supports C++11 features with -std=c++11... no
checking whether to enable C++11 support... no
Existem outras opções que habilitam recursos da STL, comparáveis à configuração do CMake descrita acima:
--enable-stl use C++ STL
--disable-stl do not use C++ STL (default)
--enable-stl-vector use C++ STL vector
--disable-stl-vector do not use C++ STL vector
--enable-stl-algorithm use C++ STL algorithm
--disable-stl-algorithm do not use C++ STL algorithm- ....
O suporte para definir versões de C++ posteriores ao C++11 ainda não está disponível nas configurações do Autoconf do DCMTK.