Pergunta

Existe uma maneira de obter o C / C ++ pré-processador ou um modelo ou como a mangle / hash __FILE__ e __LINE__ e talvez alguma outra entrada externa como uma build-número em um único número curto que pode ser citado em registros ou mensagens de erro?

(A intenção seria a de ser capaz de revertê-la (para uma lista de candidatos, se a sua lossy), quando necessário quando um cliente cita em um relatório de bug.)

Foi útil?

Solução

Você terá que usar uma função para executar a hashing e criar um código de __LINE__ e __FILE__ como o pré-processador C não é capaz de fazer tais tarefas complexas.

De qualquer forma, você pode tirar inspiração por este artigo para ver se um solução diferente pode ser mais adequado à sua situação.

Outras dicas

Bem ... você poderia usar algo como:

((*(int*)__FILE__ && 0xFFFF0000) | version << 8 | __LINE__ )

Não seria perfeitamente original, mas ele pode trabalhar para o que você quer. Poderia mudar essas RUP para +, que pode funcionar melhor para algumas coisas.

Naturalmente, se você pode realmente criar um código hash, você provavelmente vai querer fazer isso.

Eu precisava valuse série em um projeto meu e tenho-os, fazendo um modelo que se especializou em __LINE__ e __FILE__ e resultou em um int, bem como de geração (como saída tempo de compilação para stdout) uma especialização de modelo para ele é entradas que resultaram no número de linha de base nesse modelo. Estes foram coletados pela primeira vez através do compilador e, em seguida, despejado em um arquivo de código e o programa foi compilado novamente. Esse tempo cada local que o modelo foi utilizado tem um número diferente.

(feito em D, de modo que pode não ser possível em C ++)

template Serial(char[] file, int line)
{
    prgams(msg, 
    "template Serial(char[] file : \"~file~"\", int line : "~line.stringof~")"
      "{const int Serial = __LINE__;");
    const int Serial = -1;
}

A solução mais simples seria a de manter um estático "localização de erro" variável global.

#ifdef DEBUG
#define trace_here(version) printf("[%d]%s:%d {%d}\n", version, __FILE__, __LINE__, errloc++);
#else
#define trace_here(version) printf("{%lu}\n", version<<16|errloc++);
#endif

Ou sem a printf .. Basta incrementar a toda errloc você cruza uma tracepoint. Então você pode correlacionar o valor para a linha / número / versão cuspir pelo seu compilações de depuração muito facilmente.

Você precisaria incluir versão ou número de compilação, porque esses locais de erro poderia mudar a qualquer construção.

não funciona bem se você não pode reproduzir os caminhos de código.

__ FILE__ é um ponteiro para o segmento constantes do seu programa. Se você saída a diferença entre isso e alguma outra constante que você deve obter um resultado que é independente de qualquer deslocalização, etc:

extern const char g_DebugAnchor;
#define FILE_STR_OFFSET (__FILE__ - &g_DebugAnchor)

Você pode, então, relatam que, ou combiná-lo de alguma forma com o número da linha, etc. Os bits do meio de FILE_STR_OFFSET são provavelmente o mais interessante.

Bem, se você está exibindo a mensagem para o usuário se (em oposição a ter um endereço ou função acidente ser exibido pelo sistema), não há nada para mantê-lo de exibir exatamente o que você quer.

Por exemplo:

typedef union ErrorCode {
    struct {
        unsigned int file: 15;
        unsigned int line: 12; /* Better than 5 bits, still not great
                                  Thanks commenters!! */
        unsigned int build: 5;
    } bits;
    unsigned int code;
} ErrorCode;

unsigned int buildErrorCodes(const char *file, int line, int build)
{
    ErrorCode code;
    code.bits.line=line   & ((1<<12) - 1);
    code.bits.build=build & ((1<< 5) - 1);
    code.bits.file=some_hash_function(file) & ((1<<15) - 1);

    return code.code;
}

Você usaria isso como

buildErrorCodes(__FILE__, __LINE__, BUILD_CODE) 

e sua saída será em hexadecimal. Não seria muito difícil para decodificar ...

(Editado - os comentaristas estão corretos, I deve ter sido nozes para especificar 5 bits para o número da linha Modulo 4096, no entanto, linhas com mensagens de erro não são susceptíveis de colidir 5 bits para construção ainda está bem.. - módulo 32 significa que apenas 32 constrói pode ser excelente e tem o erro ainda acontecem na mesma linha.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top