Estou tentando descobrir qual versão do Boost meu código pensa que está usando. Eu quero fazer algo assim:
#error BOOST_VERSION
mas o pré-processador não expande BOOST_VERSION.
Eu sei que poderia imprimi-lo em tempo de execução a partir do programa e sei que poderia olhar a saída do pré-processador para encontrar a resposta. Acho que ter uma maneira de fazer isso durante a compilação pode ser útil.
macros
c-preprocessor
boost-preprocessor
Jim Hunziker
fonte
fonte
Respostas:
Eu sei que isso é muito tempo depois da consulta original, mas ainda pode ser útil.
Isso pode ser feito no GCC usando o operador stringify "#", mas requer dois estágios.
O valor de uma macro pode então ser exibido com:
Veja: 3.4 Stringificação na documentação online do gcc.
Como funciona:
O pré-processador entende strings entre aspas e as trata de maneira diferente do texto normal. A concatenação de strings é um exemplo desse tratamento especial. O pragma da mensagem requer um argumento que é uma string entre aspas. Quando há mais de um componente para o argumento, todos eles devem ser strings para que a concatenação de strings possa ser aplicada. O pré-processador nunca pode assumir que uma string sem aspas deva ser tratada como se estivesse entre aspas. Se sim, então:
não compilaria.
Agora considere:
que é equivalente a
Isso causa um aviso do pré-processador porque abc (sem aspas) não pode ser concatenado com a string anterior.
Agora considere o pré-processador stringize (que já foi chamado de stringification, os links na documentação foram alterados para refletir a terminologia revisada. (Ambos os termos, aliás, são igualmente detestáveis. O termo correto é, obviamente, stringifaction. Esteja pronto para atualizar seus links.)) operador. Isso atua apenas nos argumentos de uma macro e substitui o argumento não expandido pelo argumento entre aspas duplas. Portanto:
irá atribuir valores idênticos a s1 e s2. Se você executar gcc -E, poderá ver isso na saída. Talvez STR fosse melhor denominado algo como ENQUOTE.
Isso resolve o problema de colocar aspas em torno de um item não cotado, o problema agora é que, se o argumento for uma macro, a macro não será expandida. É por isso que a segunda macro é necessária. O XSTR expande seu argumento e chama STR para colocar o valor expandido entre aspas.
fonte
__IPHONE_9_3
.BOOST_PP_STRINGIZE
parece uma solução excelente para C ++, mas não para C.Aqui está minha solução para GNU CPP:
As definições acima resultam em:
Para variáveis "definidas como interger" , "definidas como string" e "definidas mas sem valor" , elas funcionam muito bem. Apenas para a variável "não definida" , eles exibiram exatamente o mesmo que o nome da variável original. Você tem que se acostumar - ou talvez alguém possa fornecer uma solução melhor.
fonte
DEFINED_INT=(sizeof(MY_STRUCT))
, sem que osizeof
operador seja avaliado.sizeof
, no entanto, ainda curioso se há uma maneira inteligente de fazer isso.)#define masks {0xff, 0xaf, 0x0f}
Se estiver usando Visual C ++, você pode usar
#pragma message
:Edit: Obrigado a LB pelo link
Aparentemente, o equivalente GCC é (não testado):
fonte
BOOST_PP_STRINGIZE
que é bom e curto e pode ser copiado / colado.Pelo que eu sei, '#error' apenas imprimirá strings, na verdade você nem precisa usar aspas .
Você já tentou escrever vários códigos propositalmente incorretos usando "BOOST_VERSION"? Talvez algo como "blá [BOOST_VERSION] = foo;" dirá algo como "string literal 1.2.1 não pode ser usado como endereço de array". Não será uma mensagem de erro bonita, mas pelo menos mostrará o valor relevante. Você pode brincar até encontrar um erro de compilação que informe o valor.
fonte
std::vector<BOOST_VERSION>;
no gcc 4.4.1. Obrigado!Sem impulso:
defina a mesma macro novamente e o compilador HIMSELF dará um aviso.
A partir do aviso, você pode ver a localização da definição anterior.
arquivo vi de definição anterior.
fonte
__cplusplus
.No Microsoft C / C ++, você pode usar o interno
_CRT_STRINGIZE()
para imprimir constantes. Muitos dos meusstdafx.h
arquivos contêm alguma combinação destes:e produz algo como este:
fonte
Funciona mesmo se
preprocess to file
estiver ativado, mesmo se tokens inválidos estiverem presentes:fonte
Build error: #include expects "FILENAME" or <FILENAME>
. Suspiro.'
:*** WARNING C318 IN LINE 2 OF test.c: can't open file '::*/`'
Você também pode pré-processar o arquivo de origem e ver como o valor do pré-processador é avaliado.
fonte
Você está procurando
Não é ótimo se BOOST_VERSION for uma string, como assumi, mas também pode haver inteiros individuais definidos para os números principais, secundários e de revisão.
fonte
#if VARIABLE == 123
instrução imediatamente e o destaque de sintaxe me diz se é o valor que eu acho que é ou não ...Olhar para a saída do pré-processador é a coisa mais próxima da resposta que você pede.
Eu sei que você excluiu isso (e outras formas), mas não tenho certeza do porquê. Você tem um problema específico o suficiente para resolver, mas não explicou por que algum dos métodos "normais" não funciona bem para você.
fonte
Você pode escrever um programa que imprima,
BOOST_VERSION
compile e execute-o como parte de seu sistema de construção. Caso contrário, acho que você está sem sorte.fonte
BOOST_VERSION é definido no arquivo de cabeçalho boost version.hpp.
fonte
Dê uma olhada na documentação do Boost também, sobre como você está usando a macro:
Em referência a
BOOST_VERSION
, de http://www.boost.org/doc/libs/1_37_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.boost_helper_macros :fonte
Em vez de #error, tente redefinir a macro, pouco antes de ser usada. A compilação falhará e o compilador fornecerá o valor atual que ele pensa que se aplica à macro.
#define BOOST_VERSION blah
fonte