Искажение __ФАЙЛА__ и __СТРОКИ__ в коде для цитирования?

StackOverflow https://stackoverflow.com/questions/142261

  •  02-07-2019
  •  | 
  •  

Вопрос

Есть ли способ заставить препроцессор C / C ++ или шаблон или что-то подобное искажать / хэшировать __FILE__ и __LINE__ и, возможно, какой-либо другой внешний ввод, такой как номер сборки, в один короткий номер, который может быть указан в журналах или сообщениях об ошибках?

(Намерение состояло бы в том, чтобы иметь возможность изменить его (на список кандидатов, если он с потерями) при необходимости, когда клиент цитирует его в отчете об ошибке.)

Это было полезно?

Решение

Вам нужно будет использовать функцию для выполнения хеширования и создания кода из __LINE__ и __FILE__ поскольку препроцессор C не способен выполнять такие сложные задачи.

В любом случае, вы можете черпать вдохновение из этого Статья чтобы посмотреть, может ли другое решение лучше подходить к вашей ситуации.

Другие советы

Что ж...вы могли бы использовать что-то вроде:

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

Это не было бы совершенно уникальным, но могло бы сработать для того, что вы хотите.Можно было бы изменить эти параметры на +, что могло бы работать лучше для некоторых вещей.

Естественно, если вы действительно можете создать хэш-код, вы, вероятно, захотите это сделать.

Мне нужны были serial valuse в моем проекте, и я получил их, создав шаблон, специализирующийся на __LINE__ и __FILE__ и привел к int, а также к генерации (как вывода во время компиляции в стандартный вывод) специализации шаблона для его входных данных, что привело к номеру строки этого шаблона.Они были собраны в первый раз с помощью компилятора, а затем сброшены в файл кода, и программа была скомпилирована снова.В этот раз каждое местоположение, в котором использовался шаблон, получило свой номер.

(сделано на D, поэтому это может быть невозможно на 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;
}

Более простым решением было бы сохранить глобальную статическую переменную "местоположение ошибки".

#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

Или без printf..Просто увеличивайте значение errloc каждый раз, когда вы пересекаете точку трассировки.Тогда вы можете довольно легко соотнести значение со строкой / номером / версией, выдаваемой вашими отладочными сборками.

Вам нужно будет указать версию или номер сборки, потому что эти местоположения ошибок могут измениться при любой сборке.

Плохо работает, если вы не можете воспроизвести пути к коду.

__FILE__ - это указатель на сегмент констант вашей программы.Если вы выведете разницу между этой и какой-либо другой константой, вы должны получить результат, который не зависит от какого-либо перемещения и т. Д:

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

Затем вы можете сообщить об этом или каким-то образом объединить это с номером строки и т.д.Средние биты FILE_STR_OFFSET, вероятно, наиболее интересны.

Что ж, если вы сами показываете сообщение пользователю (в отличие от отображения системой адреса сбоя или функции), ничто не мешает вам отображать именно то, что вы хотите.

Например:

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;
}

Вы бы использовали это как

buildErrorCodes(__FILE__, __LINE__, BUILD_CODE) 

и выведите его в шестнадцатеричном формате.Это было бы не так уж трудно расшифровать...

(Отредактировано - комментаторы правы, я, должно быть, сошел с ума, указав 5 бит для номера строки.Однако по модулю 4096 строки с сообщениями об ошибках вряд ли столкнутся.5 бит для сборки по-прежнему в порядке - по модулю 32 означает, что только 32 сборки могут быть незавершенными И ошибка все еще возникает в той же строке.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top