2016-09-22 2 views
1

Я нашел отладочные макросы Zed Shaw на своем веб-сайте, когда его книга C «Learn C the Hard Way» была бесплатной для чтения. Первоначально он был разработан для Linux, и он работает очень хорошо, использовал его некоторое время.Портирование отладочных макросов Zed Shaw на MSVC

Теперь я начал писать код C для Windows, и я использую Visual Studio. Я хочу использовать эти макросы отладки в проекте, над которым я работаю.

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

display = al_create_display(640, 480); 
check(display, "Failed to create display"); 

Определения для макросов, которые будут использоваться в следующем:

#define clean_errno() (errno == 0 ? "None" : strerror(errno)) 
#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) 
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; } 

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

То, что я сделал, я создал clean_errno() функции, которая делает то же самое, что и макрос, но использует глобальный переменный буфер и вызывает strerror_s() скопировать в него, а затем возвращает указатель на log_err() макросъемки. Однако теперь я должен:

  • либо создать новый заголовок и C файл только для этой одной функции 3-вкладышем, который я думаю, просто в изобилии
  • или я просто объявить и реализовать функцию в заголовок макроса debug, который не считается хорошей практикой C вообще, а также очень уродливым.

Есть ли какой-нибудь другой трюк/хак, о котором я не знаю, это обеспечит элегантное и простое решение?

ответ

0

Strerror устарел, поскольку он не является потокобезопасным. Если вы не заботитесь об этом факте, вы можете, вероятно, найти какой-нибудь вариант в VS, чтобы отключить это предупреждение.

Но было бы так же просто реализовать поточно-безопасную версию, используя sterror_s(). Помните, что ваши макросы могут сделать больше, чем просто вычислять выражения, в частности, это вполне возможно выделить буфер в макросе:

#define check(A, M, ...) \ 
    if(!(A)) { \ 
     char _buffer[128]; \ 
     strerror_s(_buffer, 128, errno); \ 
     fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " (M) "\n", __FILE__, \ 
       __LINE__, errno? _buffer : "None", ##__VA_ARGS__); \ 
     errno = 0; \ 
     goto error; \ 
    } 

Я не проверял этот код, он может иметь некоторые ошибки, но это должно быть Начало.

+0

Сладкий, он практически работает, единственное, что мне пришлось изменить, чтобы скомпилировать его, было удаление скобок вокруг 'M'. Я также добавил макрос __func__ для получения еще большей информации об отладке. Спасибо за помощь! :) – pryon

Смежные вопросы